[MERGE] from trunk
bzr revid: chm@openerp.com-20130726143134-4vmzxqcb2d3fnwwx
This commit is contained in:
commit
75ff22286f
|
@ -719,7 +719,7 @@ class account_journal(osv.osv):
|
|||
'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
|
||||
'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
|
||||
'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
|
||||
'entry_posted': fields.boolean('Skip \'Draft\' State for Manual Entries', help='Check this box if you don\'t want new journal entries to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation. \nNote that journal entries that are automatically created by the system are always skipping that state.'),
|
||||
'entry_posted': fields.boolean('Autopost Created Moves', help='Check this box to automatically post entries of this journal. Note that legally, some entries may be automatically posted when the source document is validated (Invoices), whatever the status of this field.'),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=1, help="Company related to this journal"),
|
||||
'allow_date':fields.boolean('Check Date in Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'),
|
||||
|
||||
|
|
|
@ -612,6 +612,13 @@
|
|||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total">
|
||||
<div class="oe_subtotal_footer_separator oe_inline">
|
||||
<label for="balance_end" />
|
||||
</div>
|
||||
<field name="balance_end" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency_id'}"/>
|
||||
</group>
|
||||
<div class="oe_clear"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@ By far the most beautiful and full featured accounting software. OpenERP Account
|
|||
Activate features on demand, from integrated analytic accounting to budget, assets and multiple companies consolidation.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=account" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-05-15 10:09+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2013-07-24 08:53+0000\n"
|
||||
"Last-Translator: Sumonchai ( เหลา ) <sumonchai@gmail.com>\n"
|
||||
"Language-Team: Thai <th@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-05-16 05:12+0000\n"
|
||||
"X-Generator: Launchpad (build 16626)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-25 05:13+0000\n"
|
||||
"X-Generator: Launchpad (build 16700)\n"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
|
@ -42,7 +42,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
msgid "Group By..."
|
||||
msgstr ""
|
||||
msgstr "จัดกลุ่มตาม..."
|
||||
|
||||
#. module: account_asset
|
||||
#: field:asset.asset.report,gross_value:0
|
||||
|
@ -58,7 +58,7 @@ msgstr ""
|
|||
#: field:asset.asset.report,asset_id:0
|
||||
#: model:ir.model,name:account_asset.model_account_asset_asset
|
||||
msgid "Asset"
|
||||
msgstr ""
|
||||
msgstr "สินทรัพย์"
|
||||
|
||||
#. module: account_asset
|
||||
#: help:account.asset.asset,prorata:0
|
||||
|
@ -72,7 +72,7 @@ msgstr ""
|
|||
#: selection:account.asset.asset,method:0
|
||||
#: selection:account.asset.category,method:0
|
||||
msgid "Linear"
|
||||
msgstr ""
|
||||
msgstr "เชิงเส้น"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,company_id:0
|
||||
|
@ -80,24 +80,24 @@ msgstr ""
|
|||
#: view:asset.asset.report:0
|
||||
#: field:asset.asset.report,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
msgstr "บริษัท"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.modify:0
|
||||
msgid "Modify"
|
||||
msgstr ""
|
||||
msgstr "ปรับเปลี่ยน"
|
||||
|
||||
#. module: account_asset
|
||||
#: selection:account.asset.asset,state:0
|
||||
#: view:asset.asset.report:0
|
||||
#: selection:asset.asset.report,state:0
|
||||
msgid "Running"
|
||||
msgstr ""
|
||||
msgstr "กำลังทำงานอยู่"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
msgid "Set to Draft"
|
||||
msgstr ""
|
||||
msgstr "กำหนดให้เป็นแบบร่าง"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
|
@ -110,7 +110,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:asset.modify,name:0
|
||||
msgid "Reason"
|
||||
msgstr ""
|
||||
msgstr "เหตุผล"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,method_progress_factor:0
|
||||
|
@ -122,7 +122,7 @@ msgstr ""
|
|||
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_list_normal
|
||||
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_list_normal
|
||||
msgid "Asset Categories"
|
||||
msgstr ""
|
||||
msgstr "หมวดหมู่สินทรัพย์"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
|
@ -173,7 +173,7 @@ msgstr ""
|
|||
#: model:ir.ui.menu,name:account_asset.menu_finance_assets
|
||||
#: model:ir.ui.menu,name:account_asset.menu_finance_config_assets
|
||||
msgid "Assets"
|
||||
msgstr ""
|
||||
msgstr "สินทรัพย์"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.category,account_depreciation_id:0
|
||||
|
@ -187,7 +187,7 @@ msgstr ""
|
|||
#: view:asset.modify:0
|
||||
#: field:asset.modify,note:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
msgstr "บันทึกย่อ"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.depreciation.line,move_id:0
|
||||
|
@ -221,7 +221,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.asset,code:0
|
||||
msgid "Reference"
|
||||
msgstr ""
|
||||
msgstr "อ้างถึง"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
|
@ -246,7 +246,7 @@ msgstr ""
|
|||
#: view:asset.asset.report:0
|
||||
#: selection:asset.asset.report,state:0
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
msgstr "ฉบับร่าง"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
|
@ -273,13 +273,13 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.category,account_analytic_id:0
|
||||
msgid "Analytic account"
|
||||
msgstr ""
|
||||
msgstr "วิเคราะห์บัญชี"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,method:0
|
||||
#: field:account.asset.category,method:0
|
||||
msgid "Computation Method"
|
||||
msgstr ""
|
||||
msgstr "วิธีการคำนวณ"
|
||||
|
||||
#. module: account_asset
|
||||
#: constraint:account.asset.asset:0
|
||||
|
@ -308,7 +308,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.asset,salvage_value:0
|
||||
msgid "Salvage Value"
|
||||
msgstr ""
|
||||
msgstr "มูลค่าซาก"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,category_id:0
|
||||
|
@ -364,20 +364,20 @@ msgstr ""
|
|||
#: field:account.asset.category,method_time:0
|
||||
#: field:account.asset.history,method_time:0
|
||||
msgid "Time Method"
|
||||
msgstr ""
|
||||
msgstr "วิธีการจัดการเวลา"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.depreciation.confirmation.wizard:0
|
||||
#: view:asset.modify:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "หรือ"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,note:0
|
||||
#: field:account.asset.category,note:0
|
||||
#: field:account.asset.history,note:0
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
msgstr "บันทึกย่อ"
|
||||
|
||||
#. module: account_asset
|
||||
#: help:account.asset.history,method_time:0
|
||||
|
@ -409,7 +409,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
msgstr "ปิด"
|
||||
|
||||
#. module: account_asset
|
||||
#: help:account.asset.asset,state:0
|
||||
|
@ -425,13 +425,13 @@ msgstr ""
|
|||
#: field:account.asset.asset,state:0
|
||||
#: field:asset.asset.report,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
msgstr "สถานะ"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,partner_id:0
|
||||
#: field:asset.asset.report,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
msgstr "พาร์ทเนอร์"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.asset.report:0
|
||||
|
@ -451,7 +451,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.history,user_id:0
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
msgstr "ผู้ใช้"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.category,account_asset_id:0
|
||||
|
@ -482,12 +482,12 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.asset,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
msgstr "เปิดใช้งาน"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.depreciation.line,parent_state:0
|
||||
msgid "State of Asset"
|
||||
msgstr ""
|
||||
msgstr "สถานะของสินทรัพย์"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.depreciation.line,name:0
|
||||
|
@ -498,12 +498,12 @@ msgstr ""
|
|||
#: view:account.asset.asset:0
|
||||
#: field:account.asset.asset,history_ids:0
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
msgstr "ประวัติ"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:asset.depreciation.confirmation.wizard:0
|
||||
msgid "Compute Asset"
|
||||
msgstr ""
|
||||
msgstr "คำนวณสินทรัพย์"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:asset.depreciation.confirmation.wizard,period_id:0
|
||||
|
@ -513,7 +513,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "ทั่วไป"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,prorata:0
|
||||
|
@ -524,7 +524,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: model:ir.model,name:account_asset.model_account_invoice
|
||||
msgid "Invoice"
|
||||
msgstr ""
|
||||
msgstr "ใบแจ้งหนี้"
|
||||
|
||||
#. module: account_asset
|
||||
#: view:account.asset.asset:0
|
||||
|
@ -535,13 +535,13 @@ msgstr ""
|
|||
#: view:asset.depreciation.confirmation.wizard:0
|
||||
#: view:asset.modify:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "ยกเลิก"
|
||||
|
||||
#. module: account_asset
|
||||
#: selection:account.asset.asset,state:0
|
||||
#: selection:asset.asset.report,state:0
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
msgstr "ปิด"
|
||||
|
||||
#. module: account_asset
|
||||
#: model:ir.model,name:account_asset.model_account_move_line
|
||||
|
@ -558,7 +558,7 @@ msgstr ""
|
|||
#: view:asset.asset.report:0
|
||||
#: field:asset.asset.report,purchase_date:0
|
||||
msgid "Purchase Date"
|
||||
msgstr ""
|
||||
msgstr "วันที่ซื้อ"
|
||||
|
||||
#. module: account_asset
|
||||
#: selection:account.asset.asset,method:0
|
||||
|
@ -606,7 +606,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.asset,currency_id:0
|
||||
msgid "Currency"
|
||||
msgstr ""
|
||||
msgstr "สกุลเงิน"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.category,journal_id:0
|
||||
|
@ -637,7 +637,7 @@ msgstr ""
|
|||
#: view:asset.asset.report:0
|
||||
#: field:asset.asset.report,move_check:0
|
||||
msgid "Posted"
|
||||
msgstr ""
|
||||
msgstr "ลงบัญชีแล้ว"
|
||||
|
||||
#. module: account_asset
|
||||
#: model:ir.actions.act_window,help:account_asset.action_asset_asset_report
|
||||
|
@ -660,7 +660,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.category,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "ชื่อ"
|
||||
|
||||
#. module: account_asset
|
||||
#: help:account.asset.category,open_asset:0
|
||||
|
@ -672,7 +672,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:asset.asset.report,name:0
|
||||
msgid "Year"
|
||||
msgstr ""
|
||||
msgstr "ปี"
|
||||
|
||||
#. module: account_asset
|
||||
#: model:ir.model,name:account_asset.model_account_asset_depreciation_line
|
||||
|
@ -693,7 +693,7 @@ msgid "Amount of Depreciation Lines"
|
|||
msgstr ""
|
||||
|
||||
#. module: account_asset
|
||||
#: code:addons/account_asset/wizard/wizard_asset_compute.py:49
|
||||
#: code:addons/account_asset/wizard/wizard_asset_compute.py:50
|
||||
#, python-format
|
||||
msgid "Created Asset Moves"
|
||||
msgstr ""
|
||||
|
@ -701,7 +701,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.depreciation.line,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
msgstr "ลำดับ"
|
||||
|
||||
#. module: account_asset
|
||||
#: help:account.asset.category,method_period:0
|
||||
|
@ -711,7 +711,7 @@ msgstr ""
|
|||
#. module: account_asset
|
||||
#: field:account.asset.history,date:0
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
msgstr "วันที่"
|
||||
|
||||
#. module: account_asset
|
||||
#: field:account.asset.asset,method_number:0
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-04-26 16:01+0000\n"
|
||||
"PO-Revision-Date: 2013-07-10 09:54+0000\n"
|
||||
"Last-Translator: Els Van Vossel (Agaplan) <Unknown>\n"
|
||||
"Language-Team: Els Van Vossel\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-04-27 05:44+0000\n"
|
||||
"X-Generator: Launchpad (build 16580)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-11 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16696)\n"
|
||||
"Language: nl\n"
|
||||
|
||||
#. module: account_voucher
|
||||
|
@ -28,7 +28,7 @@ msgid "account.config.settings"
|
|||
msgstr "account.config.settings"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:369
|
||||
#: code:addons/account_voucher/account_voucher.py:417
|
||||
#, python-format
|
||||
msgid "Write-Off"
|
||||
msgstr "Afschrijving"
|
||||
|
@ -132,7 +132,7 @@ msgid "Voucher Statistics"
|
|||
msgstr "Boekingsstatistieken"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1547
|
||||
#: code:addons/account_voucher/account_voucher.py:1641
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can not change the journal as you already reconciled some statement "
|
||||
|
@ -233,8 +233,8 @@ msgid "Journal Item"
|
|||
msgstr "Boekingslijn"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:508
|
||||
#: code:addons/account_voucher/account_voucher.py:981
|
||||
#: code:addons/account_voucher/account_voucher.py:558
|
||||
#: code:addons/account_voucher/account_voucher.py:1073
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr "Fout"
|
||||
|
@ -261,7 +261,7 @@ msgid "Cancelled"
|
|||
msgstr "Geannuleerd"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1153
|
||||
#: code:addons/account_voucher/account_voucher.py:1249
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have to configure account base code and account tax code on the '%s' tax!"
|
||||
|
@ -313,7 +313,7 @@ msgid "Tax"
|
|||
msgstr "Btw"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:879
|
||||
#: code:addons/account_voucher/account_voucher.py:971
|
||||
#, python-format
|
||||
msgid "Invalid Action!"
|
||||
msgstr "Ongeldige actie"
|
||||
|
@ -366,10 +366,10 @@ msgid "Import Invoices"
|
|||
msgstr "Facturen importeren"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1112
|
||||
#: code:addons/account_voucher/account_voucher.py:1208
|
||||
#, python-format
|
||||
msgid "Wrong voucher line"
|
||||
msgstr ""
|
||||
msgstr "Verkeerde betalingsregel"
|
||||
|
||||
#. module: account_voucher
|
||||
#: selection:account.voucher,pay_now:0
|
||||
|
@ -385,7 +385,7 @@ msgid "Receipt"
|
|||
msgstr "Reçu"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1018
|
||||
#: code:addons/account_voucher/account_voucher.py:1110
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You should configure the 'Gain Exchange Rate Account' in the accounting "
|
||||
|
@ -409,7 +409,7 @@ msgstr "Periode"
|
|||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
#: code:addons/account_voucher/account_voucher.py:211
|
||||
#: code:addons/account_voucher/account_voucher.py:231
|
||||
#, python-format
|
||||
msgid "Supplier"
|
||||
msgstr "Leverancier"
|
||||
|
@ -430,7 +430,7 @@ msgid "Debit"
|
|||
msgstr "Debet"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1547
|
||||
#: code:addons/account_voucher/account_voucher.py:1641
|
||||
#, python-format
|
||||
msgid "Unable to change journal !"
|
||||
msgstr "Het dagboek kan niet worden gewijzigd"
|
||||
|
@ -469,6 +469,12 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Klik hier als u een nieuwe leveranciersbetaling wilt maken.\n"
|
||||
" </p><p>\n"
|
||||
" Met OpenERP kunt u betalingen aan leveranciers opvolgen.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0
|
||||
|
@ -536,7 +542,7 @@ msgid "Pay Invoice"
|
|||
msgstr "Factuur betalen"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1153
|
||||
#: code:addons/account_voucher/account_voucher.py:1249
|
||||
#, python-format
|
||||
msgid "No Account Base Code and Account Tax Code!"
|
||||
msgstr "Geen rekening voor basisvak en btw-vak"
|
||||
|
@ -590,15 +596,15 @@ msgid "To Review"
|
|||
msgstr "Te controleren"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1025
|
||||
#: code:addons/account_voucher/account_voucher.py:1039
|
||||
#: code:addons/account_voucher/account_voucher.py:1194
|
||||
#: code:addons/account_voucher/account_voucher.py:1120
|
||||
#: code:addons/account_voucher/account_voucher.py:1134
|
||||
#: code:addons/account_voucher/account_voucher.py:1286
|
||||
#, python-format
|
||||
msgid "change"
|
||||
msgstr "wijzigen"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1014
|
||||
#: code:addons/account_voucher/account_voucher.py:1106
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You should configure the 'Loss Exchange Rate Account' in the accounting "
|
||||
|
@ -656,6 +662,7 @@ msgstr "Maand"
|
|||
#. module: account_voucher
|
||||
#: field:account.voucher,currency_id:0
|
||||
#: field:account.voucher.line,currency_id:0
|
||||
#: model:ir.model,name:account_voucher.model_res_currency
|
||||
#: field:sale.receipt.report,currency_id:0
|
||||
msgid "Currency"
|
||||
msgstr "Munt"
|
||||
|
@ -699,7 +706,7 @@ msgid "Reconcile Payment Balance"
|
|||
msgstr "Betalingssaldo afpunten"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:975
|
||||
#: code:addons/account_voucher/account_voucher.py:1067
|
||||
#, python-format
|
||||
msgid "Configuration Error !"
|
||||
msgstr "Configuratiefout"
|
||||
|
@ -764,7 +771,7 @@ msgid "October"
|
|||
msgstr "Oktober"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:976
|
||||
#: code:addons/account_voucher/account_voucher.py:1068
|
||||
#, python-format
|
||||
msgid "Please activate the sequence of selected journal !"
|
||||
msgstr "Gelieve de nummering van het gekozen journaal te activeren."
|
||||
|
@ -844,7 +851,7 @@ msgid "Previous Payments ?"
|
|||
msgstr "Vorige betalingen?"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1112
|
||||
#: code:addons/account_voucher/account_voucher.py:1208
|
||||
#, python-format
|
||||
msgid "The invoice you are willing to pay is not valid anymore."
|
||||
msgstr "De factuur die u wilt betalen, is niet meer geldig."
|
||||
|
@ -876,7 +883,7 @@ msgid "Active"
|
|||
msgstr "Actief"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:982
|
||||
#: code:addons/account_voucher/account_voucher.py:1074
|
||||
#, python-format
|
||||
msgid "Please define a sequence on the journal."
|
||||
msgstr "Gelieve een reeks in te stellen voor het journaal."
|
||||
|
@ -1004,7 +1011,7 @@ msgid "Journal Items"
|
|||
msgstr "Boekingslijnen"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:508
|
||||
#: code:addons/account_voucher/account_voucher.py:558
|
||||
#, python-format
|
||||
msgid "Please define default credit/debit accounts on the journal \"%s\"."
|
||||
msgstr "Stel een standaard debet-/creditrekening in voor journaal \"%s\"."
|
||||
|
@ -1221,7 +1228,7 @@ msgstr ""
|
|||
"Het bedrag van het reçu moet gelijk zijn aan het bedrag op de uittreksellijn."
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:879
|
||||
#: code:addons/account_voucher/account_voucher.py:971
|
||||
#, python-format
|
||||
msgid "Cannot delete voucher(s) which are already opened or paid."
|
||||
msgstr "Een openstaand of betaald reçu kan niet meer worden verwijderd."
|
||||
|
@ -1284,8 +1291,8 @@ msgid "Status <b>changed</b>"
|
|||
msgstr "Status <b>vgewijzigd</b>"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1014
|
||||
#: code:addons/account_voucher/account_voucher.py:1018
|
||||
#: code:addons/account_voucher/account_voucher.py:1106
|
||||
#: code:addons/account_voucher/account_voucher.py:1110
|
||||
#, python-format
|
||||
msgid "Insufficient Configuration!"
|
||||
msgstr "Niet volledig geconfigureerd"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
automatically based on your activities.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=account_voucher" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,13 +14,7 @@
|
|||
<field name="condition">True</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="state">email</field>
|
||||
<field name="email">object.user_id.email</field>
|
||||
<field name="subject">Reminder on Lead: [[object.id ]] [[object.partner_id and 'of ' +object.partner_id.name or '']]</field>
|
||||
<field name="message">Warning unprocessed incoming lead is more than 5 day old.
|
||||
Name: [[object.name ]]
|
||||
ID: [[object.id ]]
|
||||
Description: [[object.description]]
|
||||
</field>
|
||||
<field name="template_id" ref="email_template_opportunity_reminder_mail"/>
|
||||
</record>
|
||||
<record id="rule_set_reminder_lead" model="base.action.rule">
|
||||
<field name="name">Set Auto Reminder on leads which are not open since 5 days.</field>
|
||||
|
|
|
@ -621,7 +621,7 @@ class crm_lead(format_address, osv.osv):
|
|||
attachment.write(values)
|
||||
return True
|
||||
|
||||
def merge_opportunity(self, cr, uid, ids, context=None):
|
||||
def merge_opportunity(self, cr, uid, ids, user_id=False, section_id=False, context=None):
|
||||
"""
|
||||
Different cases of merge:
|
||||
- merge leads together = 1 new lead
|
||||
|
@ -655,6 +655,11 @@ class crm_lead(format_address, osv.osv):
|
|||
fields = list(CRM_LEAD_FIELDS_TO_MERGE)
|
||||
merged_data = self._merge_data(cr, uid, ids, highest, fields, context=context)
|
||||
|
||||
if user_id:
|
||||
merged_data['user_id'] = user_id
|
||||
if section_id:
|
||||
merged_data['section_id'] = section_id
|
||||
|
||||
# Merge messages and attachements into the first opportunity
|
||||
self._merge_opportunity_history(cr, uid, highest.id, tail_opportunities, context=context)
|
||||
self._merge_opportunity_attachments(cr, uid, highest.id, tail_opportunities, context=context)
|
||||
|
@ -940,42 +945,6 @@ class crm_lead(format_address, osv.osv):
|
|||
vals.update(onchange_stage_values)
|
||||
return super(crm_lead, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def new_mail_send(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
This function opens a window to compose an email, with the edi sale template message loaded by default
|
||||
'''
|
||||
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
|
||||
ir_model_data = self.pool.get('ir.model.data')
|
||||
try:
|
||||
template_id = ir_model_data.get_object_reference(cr, uid, 'crm', 'email_template_opportunity_mail')[1]
|
||||
except ValueError:
|
||||
template_id = False
|
||||
try:
|
||||
compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1]
|
||||
except ValueError:
|
||||
compose_form_id = False
|
||||
if context is None:
|
||||
context = {}
|
||||
ctx = context.copy()
|
||||
ctx.update({
|
||||
'default_model': 'crm.lead',
|
||||
'default_res_id': ids[0],
|
||||
'default_use_template': bool(template_id),
|
||||
'default_template_id': template_id,
|
||||
'default_composition_mode': 'comment',
|
||||
})
|
||||
return {
|
||||
'name': _('Compose Email'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.compose.message',
|
||||
'views': [(compose_form_id, 'form')],
|
||||
'view_id': compose_form_id,
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
}
|
||||
|
||||
# ----------------------------------------
|
||||
# Mail Gateway
|
||||
# ----------------------------------------
|
||||
|
|
|
@ -220,6 +220,20 @@
|
|||
<field name="email_to">${not object.partner_id and object.email_from}</field>
|
||||
<field name="body_html"></field>
|
||||
</record>
|
||||
<record id="email_template_opportunity_reminder_mail" model="email.template">
|
||||
<field name="name">Reminder to User</field>
|
||||
<field name="model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="email_from">admin@example.com</field>
|
||||
<field name="email_to">${object.user_id != False and object.user_id.email}</field>
|
||||
<field name="subject">Reminder on Lead: ${object.id} from ${object.partner_id != False and object.partner_id.name or object.contact_name}</field>
|
||||
<field name="body_html"><![CDATA[<p>This opportunity did not have any activity since at least 5 days. Here are some details:</p>
|
||||
<ul>
|
||||
<li>Name: ${object.name}</li>
|
||||
<li>ID: ${object.id}</li>
|
||||
<li>Description: ${object.description}</field></li>
|
||||
</ul>]]></field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -408,7 +408,7 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="partner_id"
|
||||
on_change="onchange_partner_id(partner_id, email_from)"
|
||||
on_change="on_change_partner_id(partner_id)"
|
||||
string="Customer"
|
||||
context="{'default_name': partner_name, 'default_email': email_from, 'default_phone': phone}"/>
|
||||
<field name="email_from" string="Email"/>
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-07-09 07:36+0000\n"
|
||||
"PO-Revision-Date: 2013-07-25 13:52+0000\n"
|
||||
"Last-Translator: krnkris <Unknown>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-10 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16696)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-26 05:14+0000\n"
|
||||
"X-Generator: Launchpad (build 16700)\n"
|
||||
|
||||
#. module: crm
|
||||
#: model:crm.case.stage,name:crm.stage_lead3
|
||||
|
@ -241,7 +241,7 @@ msgstr "Kilép"
|
|||
#: view:crm.lead:0
|
||||
#: field:crm.lead,state_id:0
|
||||
msgid "State"
|
||||
msgstr "Állapot"
|
||||
msgstr "Állam/Megye"
|
||||
|
||||
#. module: crm
|
||||
#: field:res.partner,meeting_count:0
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2012-12-19 07:22+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2013-07-23 03:21+0000\n"
|
||||
"Last-Translator: fanvil <fanvil@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: 2013-03-16 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 16532)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-24 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16700)\n"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead.report:0
|
||||
|
@ -29,7 +29,7 @@ msgid ""
|
|||
msgstr "允许你设置接收邮件服务器,并从收到的邮件中创建线索"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:881
|
||||
#: code:addons/crm/crm_lead.py:898
|
||||
#: selection:crm.case.stage,type:0
|
||||
#: view:crm.lead:0
|
||||
#: selection:crm.lead,type:0
|
||||
|
@ -54,6 +54,11 @@ msgid ""
|
|||
"Description: [[object.description]]\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"警告收到的新线索已超过5天未处理\n"
|
||||
"名称:[[object.name]]\n"
|
||||
"编号:[[object.id]]\n"
|
||||
"描述:[[object.description]]\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.opportunity2phonecall,action:0
|
||||
|
@ -64,7 +69,7 @@ msgstr "动作"
|
|||
#. module: crm
|
||||
#: model:ir.actions.server,name:crm.action_set_team_sales_department
|
||||
msgid "Set team to Sales Department"
|
||||
msgstr ""
|
||||
msgstr "设置团队 到销售部"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead2opportunity.partner.mass:0
|
||||
|
@ -151,7 +156,7 @@ msgstr "规则名称"
|
|||
#: code:addons/crm/crm_phonecall.py:280
|
||||
#, python-format
|
||||
msgid "It's only possible to convert one phonecall at a time."
|
||||
msgstr ""
|
||||
msgstr "每次只能转换一个电话呼叫"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.case.resource.type:0
|
||||
|
@ -180,11 +185,11 @@ msgstr "预计结束月份"
|
|||
msgid ""
|
||||
"Holds the Chatter summary (number of messages, ...). This summary is "
|
||||
"directly in html format in order to be inserted in kanban views."
|
||||
msgstr ""
|
||||
msgstr "保留复杂的摘要(消息数量,……等)。为了插入到看板视图,这一摘要直接是是HTML格式。"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:624
|
||||
#: code:addons/crm/crm_lead.py:744
|
||||
#: code:addons/crm/crm_lead.py:640
|
||||
#: code:addons/crm/crm_lead.py:761
|
||||
#: code:addons/crm/crm_phonecall.py:280
|
||||
#, python-format
|
||||
msgid "Warning!"
|
||||
|
@ -232,7 +237,7 @@ msgstr "状态"
|
|||
#. module: crm
|
||||
#: field:res.partner,meeting_count:0
|
||||
msgid "# Meetings"
|
||||
msgstr ""
|
||||
msgstr "#会议"
|
||||
|
||||
#. module: crm
|
||||
#: model:ir.actions.server,name:crm.action_email_reminder_lead
|
||||
|
@ -252,7 +257,7 @@ msgstr "排除的答案:"
|
|||
#. module: crm
|
||||
#: model:ir.model,name:crm.model_crm_merge_opportunity
|
||||
msgid "Merge opportunities"
|
||||
msgstr ""
|
||||
msgstr "合并商机"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead.report:0
|
||||
|
@ -265,7 +270,7 @@ msgstr "线索分析"
|
|||
#: code:addons/crm/crm_lead.py:1010
|
||||
#, python-format
|
||||
msgid "<b>%s a call</b> for the <em>%s</em>."
|
||||
msgstr ""
|
||||
msgstr "<b>%s 一个电话</b> 为了 <em>%s</em>."
|
||||
|
||||
#. module: crm
|
||||
#: model:ir.actions.act_window,name:crm.crm_case_resource_type_act
|
||||
|
@ -293,7 +298,7 @@ msgid "Prospect Partner"
|
|||
msgstr "潜在业务伙伴"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:982
|
||||
#: code:addons/crm/crm_lead.py:1002
|
||||
#, python-format
|
||||
msgid "No Subject"
|
||||
msgstr "无主题"
|
||||
|
@ -323,6 +328,18 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" "
|
||||
"点击创建新客户分组\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"创建指定的分类用于赋值给你的联系人\n"
|
||||
" "
|
||||
"以便更好管理你和他们的联系。分组工具\n"
|
||||
" "
|
||||
"可以根据你预设的条件给联系人分配组。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.opportunity2phonecall,contact_name:0
|
||||
|
@ -445,16 +462,16 @@ msgid "#Opportunities"
|
|||
msgstr "#商机"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:624
|
||||
#: code:addons/crm/crm_lead.py:640
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please select more than one element (lead or opportunity) from the list view."
|
||||
msgstr ""
|
||||
msgstr "请从列表视图中选择一个以上元素(线索或机会)。"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
msgid "Leads that are assigned to one of the sale teams I manage, or to me"
|
||||
msgstr ""
|
||||
msgstr "分配给我锁管理的某个销售队伍,或给我的线索。"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.lead,partner_address_email:0
|
||||
|
@ -473,6 +490,16 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" "
|
||||
"点击创建新的销售团队\n"
|
||||
" <p></p>\n"
|
||||
" "
|
||||
"使用销售团队,把不同销售员或部门组织成独立的团队。\n"
|
||||
" "
|
||||
"每个团队会使用自己的商机列表工作。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: model:process.transition,note:crm.process_transition_opportunitymeeting0
|
||||
|
@ -511,7 +538,7 @@ msgstr "邮件"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,description:crm.mt_lead_stage
|
||||
msgid "Stage changed"
|
||||
msgstr ""
|
||||
msgstr "任务阶段已改变"
|
||||
|
||||
#. module: crm
|
||||
#: selection:crm.lead.report,creation_month:0
|
||||
|
@ -572,7 +599,7 @@ msgstr "合并"
|
|||
#. module: crm
|
||||
#: model:email.template,subject:crm.email_template_opportunity_mail
|
||||
msgid "Opportunity ${object.name | h})"
|
||||
msgstr ""
|
||||
msgstr "商机${object.name | h})"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.case.categ:0
|
||||
|
@ -590,6 +617,8 @@ msgid ""
|
|||
"Reminder on Lead: [[object.id ]] [[object.partner_id and 'of ' "
|
||||
"+object.partner_id.name or '']]"
|
||||
msgstr ""
|
||||
"线索:[[object.id ]] [[object.partner_id and 'of ' +object.partner_id.name or "
|
||||
"'']]的提醒"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.segmentation:0
|
||||
|
@ -630,6 +659,13 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" 点击创建新类型\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"创建指定的电话类型,更好地定义系统中记录的电话类型\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: help:crm.case.section,reply_to:0
|
||||
|
@ -712,7 +748,7 @@ msgid "Statistics Dashboard"
|
|||
msgstr "统计控制台"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:861
|
||||
#: code:addons/crm/crm_lead.py:878
|
||||
#: model:crm.case.stage,name:crm.stage_lead2
|
||||
#: selection:crm.case.stage,type:0
|
||||
#: view:crm.lead:0
|
||||
|
@ -738,7 +774,7 @@ msgstr "转为商机"
|
|||
#. module: crm
|
||||
#: model:ir.model,name:crm.model_sale_config_settings
|
||||
msgid "sale.config.settings"
|
||||
msgstr ""
|
||||
msgstr "sale.config.settings"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.segmentation:0
|
||||
|
@ -759,7 +795,7 @@ msgstr "查询电话访问"
|
|||
#: view:crm.lead.report:0
|
||||
msgid ""
|
||||
"Leads/Opportunities that are assigned to one of the sale teams I manage"
|
||||
msgstr ""
|
||||
msgstr "分配给我所管理的某个销售团队的线索/商机。"
|
||||
|
||||
#. module: crm
|
||||
#: field:calendar.attendee,categ_id:0
|
||||
|
@ -772,7 +808,7 @@ msgid "Exclusive"
|
|||
msgstr "唯一的"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:584
|
||||
#: code:addons/crm/crm_lead.py:600
|
||||
#, python-format
|
||||
msgid "From %s : %s"
|
||||
msgstr "发自: %s:%s"
|
||||
|
@ -866,7 +902,7 @@ msgstr "标记为已赢得"
|
|||
#. module: crm
|
||||
#: model:ir.filters,name:crm.filter_usa_lead
|
||||
msgid "Leads from USA"
|
||||
msgstr ""
|
||||
msgstr "来自USA的线索"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -917,7 +953,7 @@ msgstr "参考"
|
|||
msgid ""
|
||||
"Opportunities that are assigned to either me or one of the sale teams I "
|
||||
"manage"
|
||||
msgstr ""
|
||||
msgstr "分配给我或者我管理的某个销售团队的商机。"
|
||||
|
||||
#. module: crm
|
||||
#: help:crm.case.section,resource_calendar_id:0
|
||||
|
@ -940,7 +976,7 @@ msgid "Next Action"
|
|||
msgstr "下一动作"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:763
|
||||
#: code:addons/crm/crm_lead.py:780
|
||||
#, python-format
|
||||
msgid "<b>Partner</b> set to <em>%s</em>."
|
||||
msgstr ""
|
||||
|
@ -983,6 +1019,8 @@ msgid ""
|
|||
"Allows you to track your customers/suppliers claims and grievances.\n"
|
||||
" This installs the module crm_claim."
|
||||
msgstr ""
|
||||
"允许你记录客户/供应商的索赔和抱怨。\n"
|
||||
" 将安装crm_claim模块"
|
||||
|
||||
#. module: crm
|
||||
#: model:crm.case.stage,name:crm.stage_lead6
|
||||
|
@ -1030,10 +1068,10 @@ msgid "Creation Date"
|
|||
msgstr "创建日期"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:698
|
||||
#: code:addons/crm/crm_lead.py:715
|
||||
#, python-format
|
||||
msgid "Lead <b>converted into an Opportunity</b>"
|
||||
msgstr ""
|
||||
msgstr "线索 <b>已转换成商机</b>"
|
||||
|
||||
#. module: crm
|
||||
#: selection:crm.segmentation.line,expr_name:0
|
||||
|
@ -1094,7 +1132,7 @@ msgstr "删除"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,description:crm.mt_lead_create
|
||||
msgid "Opportunity created"
|
||||
msgstr ""
|
||||
msgstr "商机已创建"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -1123,6 +1161,17 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" 点击创建新的商机\n"
|
||||
" </p><p>\n"
|
||||
" OpenERP帮你记录你的销售管道\n"
|
||||
" 跟踪潜在销售并更好地预测未来收益\n"
|
||||
" </p><p>\n"
|
||||
" 你可以对商机安排会议或电话,\n"
|
||||
" 将他们转化成报价单,附上相关\n"
|
||||
" 文档,跟踪所有的讨论等等。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.segmentation,partner_id:0
|
||||
|
@ -1186,13 +1235,13 @@ msgstr "如果你勾选了这里,这个阶段会作为每个销售团队的默
|
|||
msgid ""
|
||||
"This field is used to distinguish stages related to Leads from stages "
|
||||
"related to Opportunities, or to specify stages available for both types."
|
||||
msgstr ""
|
||||
msgstr "此域用于区分用于线索的阶段和用于商机的阶段,或者指示同时可用于两个类型。"
|
||||
|
||||
#. module: crm
|
||||
#: model:mail.message.subtype,name:crm.mt_lead_create
|
||||
#: model:mail.message.subtype,name:crm.mt_salesteam_lead
|
||||
msgid "Lead Created"
|
||||
msgstr ""
|
||||
msgstr "线索已创建"
|
||||
|
||||
#. module: crm
|
||||
#: help:crm.segmentation,sales_purchase_active:0
|
||||
|
@ -1217,7 +1266,9 @@ msgid "Days to Close"
|
|||
msgstr "结束日期"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:1057
|
||||
#: field:crm.case.section,complete_name:0
|
||||
#, python-format
|
||||
msgid "unknown"
|
||||
msgstr "未知"
|
||||
|
||||
|
@ -1264,7 +1315,7 @@ msgid ""
|
|||
"progress the Status is set to 'Open'. When the case is over, the Status is "
|
||||
"set to 'Done'. If the case needs to be reviewed then the Status is set to "
|
||||
"'Pending'."
|
||||
msgstr ""
|
||||
msgstr "当一个创建时,状态设为‘草稿’。如果此案在进行中,被设为‘打开‘。当案子结束,状态被设为’结束‘。如果需要被审阅,状态被设为’等待‘"
|
||||
|
||||
#. module: crm
|
||||
#: model:crm.case.section,name:crm.crm_case_section_1
|
||||
|
@ -1300,7 +1351,7 @@ msgid "Lead Description"
|
|||
msgstr "销售线索描述"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:565
|
||||
#: code:addons/crm/crm_lead.py:581
|
||||
#, python-format
|
||||
msgid "Merged opportunities"
|
||||
msgstr "合并商机"
|
||||
|
@ -1373,7 +1424,7 @@ msgstr "待办事项"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,description:crm.mt_lead_lost
|
||||
msgid "Opportunity lost"
|
||||
msgstr ""
|
||||
msgstr "丢掉的商机"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.lead2opportunity.partner,action:0
|
||||
|
@ -1422,7 +1473,7 @@ msgstr "用户"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,name:crm.mt_lead_stage
|
||||
msgid "Stage Changed"
|
||||
msgstr ""
|
||||
msgstr "阶段已改变"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.case.stage,section_ids:0
|
||||
|
@ -1495,7 +1546,7 @@ msgstr "信息和通信历史记录"
|
|||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
msgid "Show Countries"
|
||||
msgstr ""
|
||||
msgstr "显示国家"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -1567,7 +1618,7 @@ msgid ""
|
|||
"The status of your document will automatically change regarding the selected "
|
||||
"stage. For example, if a stage is related to the status 'Close', when your "
|
||||
"document reaches this stage, it is automatically closed."
|
||||
msgstr ""
|
||||
msgstr "文档的状态会根据选中的阶段自动改变。如果一个阶段关联了‘关闭’状态,当文档到达这个阶段就自动被关闭。"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead2opportunity.partner.mass:0
|
||||
|
@ -1588,7 +1639,7 @@ msgstr "通话月份"
|
|||
#: code:addons/crm/crm_phonecall.py:290
|
||||
#, python-format
|
||||
msgid "Partner has been <b>created</b>."
|
||||
msgstr ""
|
||||
msgstr "合作伙伴已<b>创建</b>"
|
||||
|
||||
#. module: crm
|
||||
#: field:sale.config.settings,module_crm_claim:0
|
||||
|
@ -1602,6 +1653,7 @@ msgid ""
|
|||
"the treatment delays or number of leads per state. You can sort out your "
|
||||
"leads analysis by different groups to get accurate grained analysis."
|
||||
msgstr ""
|
||||
"线索分析允许你检查不同的关联CRM的信息,例如延迟或每个状态的线索的数量。你可以使用不同的分组对线索分析进行整理已获得精确细致的分析结果。"
|
||||
|
||||
#. module: crm
|
||||
#: model:crm.case.categ,name:crm.categ_oppor3
|
||||
|
@ -1822,7 +1874,7 @@ msgstr "销售团队"
|
|||
#. module: crm
|
||||
#: field:crm.case.stage,case_default:0
|
||||
msgid "Default to New Sales Team"
|
||||
msgstr ""
|
||||
msgstr "默认分配给新建销售团队"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -1861,10 +1913,10 @@ msgid "Leads"
|
|||
msgstr "线索"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:563
|
||||
#: code:addons/crm/crm_lead.py:579
|
||||
#, python-format
|
||||
msgid "Merged leads"
|
||||
msgstr ""
|
||||
msgstr "合并的线索"
|
||||
|
||||
#. module: crm
|
||||
#: model:crm.case.categ,name:crm.categ_oppor5
|
||||
|
@ -1887,7 +1939,7 @@ msgstr "待办"
|
|||
#: model:mail.message.subtype,name:crm.mt_lead_convert_to_opportunity
|
||||
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_opportunity
|
||||
msgid "Lead to Opportunity"
|
||||
msgstr ""
|
||||
msgstr "线索到商机"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.lead,user_email:0
|
||||
|
@ -1955,7 +2007,6 @@ msgid "Global CC"
|
|||
msgstr "完整抄送"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
#: view:crm.phonecall:0
|
||||
#: model:ir.actions.act_window,name:crm.crm_case_categ_phone0
|
||||
#: model:ir.ui.menu,name:crm.menu_crm_case_phone
|
||||
|
@ -2089,7 +2140,7 @@ msgstr "转换选项"
|
|||
msgid ""
|
||||
"Follow this salesteam to automatically track the events associated to users "
|
||||
"of this team."
|
||||
msgstr ""
|
||||
msgstr "跟踪此销售团队,自动跟踪此团队中用户关联的事件。"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2101,7 +2152,7 @@ msgstr "地址"
|
|||
msgid ""
|
||||
"The email address associated with this team. New emails received will "
|
||||
"automatically create new leads assigned to the team."
|
||||
msgstr ""
|
||||
msgstr "此邮件地址关联此团队。收到的新邮件将自动创建线索并分配给此团队。"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2193,13 +2244,24 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" 点击安排一个销售电话\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"OpenERP允许你容易地定义销售团队要打的\n"
|
||||
" 电话并根据跟踪处理。 "
|
||||
" \n"
|
||||
" </p><p> \n"
|
||||
" 你可以使用导入功能来导入新列表\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: help:crm.case.stage,fold:0
|
||||
msgid ""
|
||||
"This stage is not visible, for example in status bar or kanban view, when "
|
||||
"there are no records in that stage to display."
|
||||
msgstr ""
|
||||
msgstr "此阶段无记录可显示时,在状态栏或看板视图等处不可见。"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.lead.report,nbr:0
|
||||
|
@ -2245,7 +2307,7 @@ msgstr "运行中"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,description:crm.mt_lead_convert_to_opportunity
|
||||
msgid "Lead converted into an opportunity"
|
||||
msgstr ""
|
||||
msgstr "装换成商机的线索"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2255,7 +2317,7 @@ msgstr "未分配的线索"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,description:crm.mt_lead_won
|
||||
msgid "Opportunity won"
|
||||
msgstr ""
|
||||
msgstr "获胜的商机"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.case.categ,object_id:0
|
||||
|
@ -2321,7 +2383,7 @@ msgstr "在这报表中,你能分析你的销售团队在电话访问上的业
|
|||
#. module: crm
|
||||
#: field:crm.case.stage,fold:0
|
||||
msgid "Fold by Default"
|
||||
msgstr ""
|
||||
msgstr "默认折叠"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.case.stage,state:0
|
||||
|
@ -2357,7 +2419,7 @@ msgstr "已确认"
|
|||
#. module: crm
|
||||
#: model:ir.model,name:crm.model_crm_partner_binding
|
||||
msgid "Handle partner binding or generation in CRM wizards."
|
||||
msgstr ""
|
||||
msgstr "在CRM向导中处理合作伙伴的绑定或生成。"
|
||||
|
||||
#. module: crm
|
||||
#: model:ir.actions.act_window,name:crm.act_oppor_stage_user
|
||||
|
@ -2408,11 +2470,23 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" 点击创建一个未验证的线索。\n"
|
||||
" </p><p>\n"
|
||||
" 如果你在创建一个商机或者客户前\n"
|
||||
" 需要验证,使用线索。可以是一张收到的\n"
|
||||
" 名片,网站上收到的一个联系方式,或者\n"
|
||||
" 你导入系统的一个文件数据。\n"
|
||||
" </p><p>\n"
|
||||
" 一旦被确定,线索可以被装换成商机\n"
|
||||
" 以及/或者你的地址簿中的新客户。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: field:sale.config.settings,fetchmail_lead:0
|
||||
msgid "Create leads from incoming mails"
|
||||
msgstr ""
|
||||
msgstr "从收到的邮件创建线索"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2480,6 +2554,19 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" 点击创建电话总结\n"
|
||||
" </p><p>\n"
|
||||
" OpenERP "
|
||||
"允许你快速记录打入的电话,用来\n"
|
||||
" "
|
||||
"跟踪与用户沟通的历史,或通知另一个销售团队。\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"为了跟踪处理一个电话,你可以触发请求另一次电话,\n"
|
||||
" 一次会议或者一个商机。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: model:process.node,note:crm.process_node_leads0
|
||||
|
@ -2526,6 +2613,20 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" "
|
||||
"点击新建一个销售标签\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"创建指定的适合公司活动的标签\n"
|
||||
" "
|
||||
"用于更好地分析你的线索和商机。\n"
|
||||
" "
|
||||
"标签分类可以反映你的商品结构或者\n"
|
||||
" "
|
||||
"不同的销售类型。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: selection:crm.lead.report,creation_month:0
|
||||
|
@ -2538,7 +2639,7 @@ msgstr "8月"
|
|||
#: model:mail.message.subtype,name:crm.mt_lead_lost
|
||||
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_lost
|
||||
msgid "Opportunity Lost"
|
||||
msgstr ""
|
||||
msgstr "丢失的商机"
|
||||
|
||||
#. module: crm
|
||||
#: field:crm.lead.report,deadline_month:0
|
||||
|
@ -2634,7 +2735,7 @@ msgstr "通话日志"
|
|||
#: model:mail.message.subtype,name:crm.mt_lead_won
|
||||
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_won
|
||||
msgid "Opportunity Won"
|
||||
msgstr ""
|
||||
msgstr "获胜的商机"
|
||||
|
||||
#. module: crm
|
||||
#: model:ir.actions.act_window,name:crm.crm_case_section_act_tree
|
||||
|
@ -2773,7 +2874,7 @@ msgstr "电话访问"
|
|||
#. module: crm
|
||||
#: view:crm.phonecall.report:0
|
||||
msgid "Phone calls that are assigned to one of the sale teams I manage"
|
||||
msgstr ""
|
||||
msgstr "分配给某个我所管理的销售团队的电话。"
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2848,6 +2949,19 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" "
|
||||
"点击定义一个新渠道\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"使用渠道来记录你的线索和商机的来源。\n"
|
||||
" "
|
||||
"主要用于市场工作相关的销售分析报告。\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"渠道例子:公司网站,电话,市场活动,经销商等\n"
|
||||
" <p>\n"
|
||||
" "
|
||||
|
||||
#. module: crm
|
||||
#: view:crm.lead:0
|
||||
|
@ -2885,7 +2999,7 @@ msgid "Working Hours"
|
|||
msgstr "工作时间"
|
||||
|
||||
#. module: crm
|
||||
#: code:addons/crm/crm_lead.py:968
|
||||
#: code:addons/crm/crm_lead.py:986
|
||||
#: view:crm.lead:0
|
||||
#: field:crm.lead2opportunity.partner,partner_id:0
|
||||
#: field:crm.lead2opportunity.partner.mass,partner_id:0
|
||||
|
@ -3007,7 +3121,7 @@ msgstr "时事通信"
|
|||
#. module: crm
|
||||
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_stage
|
||||
msgid "Opportunity Stage Changed"
|
||||
msgstr ""
|
||||
msgstr "商机状态已改变"
|
||||
|
||||
#. module: crm
|
||||
#: model:ir.actions.act_window,help:crm.crm_lead_stage_act
|
||||
|
@ -3021,6 +3135,16 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" "
|
||||
"点击设置你的线索/商机管道的新阶段。\n"
|
||||
" </p><p>\n"
|
||||
" "
|
||||
"阶段允许销售人员记录特定的线索或商机\n"
|
||||
" "
|
||||
"在销售循环中的位置。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#~ msgid "My Draft "
|
||||
#~ msgstr "我的草稿 "
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
Manage your sales funnel with no effort. Attract leads, follow-up on phone calls and meetings. Analyse the quality of your leads to make informed decisions and save time by integrating emails directly into the application.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=crm" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -35,6 +35,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
('merge', 'Merge with existing opportunities')
|
||||
], 'Conversion Action', required=True),
|
||||
'opportunity_ids': fields.many2many('crm.lead', string='Opportunities'),
|
||||
'user_id': fields.many2one('res.users', 'Salesperson', select=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', select=True),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
|
@ -74,9 +76,27 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
res.update({'name' : len(tomerge) >= 2 and 'merge' or 'convert'})
|
||||
if 'opportunity_ids' in fields and len(tomerge) >= 2:
|
||||
res.update({'opportunity_ids': list(tomerge)})
|
||||
|
||||
if lead.user_id:
|
||||
res.update({'user_id': lead.user_id.id})
|
||||
if lead.section_id:
|
||||
res.update({'section_id': lead.section_id.id})
|
||||
return res
|
||||
|
||||
def on_change_user(self, cr, uid, ids, user_id, section_id, context=None):
|
||||
""" When changing the user, also set a section_id or restrict section id
|
||||
to the ones user_id is member of. """
|
||||
if user_id:
|
||||
if section_id:
|
||||
user_in_section = self.pool.get('crm.case.section').search(cr, uid, [('id', '=', section_id), '|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context, count=True)
|
||||
else:
|
||||
user_in_section = False
|
||||
if not user_in_section:
|
||||
section_id = False
|
||||
section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
|
||||
if section_ids:
|
||||
section_id = section_ids[0]
|
||||
return {'value': {'section_id': section_id}}
|
||||
|
||||
def view_init(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
Check some preconditions before the wizard executes.
|
||||
|
@ -118,15 +138,15 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
w = self.browse(cr, uid, ids, context=context)[0]
|
||||
opp_ids = [o.id for o in w.opportunity_ids]
|
||||
if w.name == 'merge':
|
||||
lead_id = self.pool.get('crm.lead').merge_opportunity(cr, uid, opp_ids, context=context)
|
||||
lead_id = self.pool.get('crm.lead').merge_opportunity(cr, uid, opp_ids, w.user_id.id, w.section_id.id, context=context)
|
||||
lead_ids = [lead_id]
|
||||
lead = self.pool.get('crm.lead').read(cr, uid, lead_id, ['type'], context=context)
|
||||
if lead['type'] == "lead":
|
||||
context.update({'active_ids': lead_ids})
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids, 'user_ids': [w.user_id.id], 'section_id': w.section_id.id}, context=context)
|
||||
else:
|
||||
lead_ids = context.get('active_ids', [])
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
|
||||
self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids, 'user_ids': [w.user_id.id], 'section_id': w.section_id.id}, context=context)
|
||||
|
||||
return self.pool.get('crm.lead').redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
<group name="name">
|
||||
<field name="name" class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Assign opportunities to">
|
||||
<field name="user_id" class="oe_inline" on_change="on_change_user(user_id, section_id, context)"/>
|
||||
<field name="section_id" class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Opportunities">
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '!=', 'merge')]}" nolabel="1">
|
||||
<tree>
|
||||
|
@ -56,6 +60,10 @@
|
|||
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
|
||||
class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Assign opportunities to" attrs="{'invisible': [('name', '=', '')]}">
|
||||
<field name="section_id" groups="base.group_multi_salesteams"/>
|
||||
<field name="user_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group string="Select Opportunities" attrs="{'invisible': [('name', '!=', 'merge')]}">
|
||||
<field name="opportunity_ids" colspan="4" nolabel="1" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
|
@ -72,12 +80,6 @@
|
|||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
<group string="Assign opportunities to" attrs="{'invisible': [('name', '=', '')]}">
|
||||
<field name="section_id" groups="base.group_multi_salesteams"/>
|
||||
<field name="user_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
|
||||
<footer>
|
||||
<button name="mass_convert" string="Convert to Opportunities" type="object" class="oe_highlight"/>
|
||||
or
|
||||
|
|
|
@ -34,6 +34,8 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
_description = 'Merge opportunities'
|
||||
_columns = {
|
||||
'opportunity_ids': fields.many2many('crm.lead', rel='merge_opportunity_rel', id1='merge_id', id2='opportunity_id', string='Leads/Opportunities'),
|
||||
'user_id': fields.many2one('res.users', 'Salesperson', select=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', select=True),
|
||||
}
|
||||
|
||||
def action_merge(self, cr, uid, ids, context=None):
|
||||
|
@ -47,7 +49,7 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
#TODO: why is this passed through the context ?
|
||||
context['lead_ids'] = [opportunity2merge_ids[0].id]
|
||||
|
||||
merge_id = lead_obj.merge_opportunity(cr, uid, [x.id for x in opportunity2merge_ids], context=context)
|
||||
merge_id = lead_obj.merge_opportunity(cr, uid, [x.id for x in opportunity2merge_ids], wizard.user_id.id, wizard.section_id.id, context=context)
|
||||
|
||||
# The newly created lead might be a lead or an opp: redirect toward the right view
|
||||
merge_result = lead_obj.browse(cr, uid, merge_id, context=context)
|
||||
|
@ -79,4 +81,19 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
|
||||
return res
|
||||
|
||||
def on_change_user(self, cr, uid, ids, user_id, section_id, context=None):
|
||||
""" When changing the user, also set a section_id or restrict section id
|
||||
to the ones user_id is member of. """
|
||||
if user_id:
|
||||
if section_id:
|
||||
user_in_section = self.pool.get('crm.case.section').search(cr, uid, [('id', '=', section_id), '|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context, count=True)
|
||||
else:
|
||||
user_in_section = False
|
||||
if not user_in_section:
|
||||
section_id = False
|
||||
section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
|
||||
if section_ids:
|
||||
section_id = section_ids[0]
|
||||
return {'value': {'section_id': section_id}}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -8,20 +8,25 @@
|
|||
<field name="model">crm.merge.opportunity</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Merge Leads/Opportunities" version="7.0">
|
||||
<separator string="Select Leads/Opportunities"/>
|
||||
<field name="opportunity_ids">
|
||||
<tree>
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="contact_name"/>
|
||||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id" groups="base.group_multi_salesteams"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group string="Assign opportunities to">
|
||||
<field name="user_id" class="oe_inline" on_change="on_change_user(user_id, context)"/>
|
||||
<field name="section_id" class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Select Leads/Opportunities">
|
||||
<field name="opportunity_ids" nolabel="1">
|
||||
<tree>
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="contact_name"/>
|
||||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id" groups="base.group_multi_salesteams"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_merge" type="object" string="Merge" class="oe_highlight"/>
|
||||
or
|
||||
|
|
|
@ -38,7 +38,7 @@ You can also use the geolocalization without using the GPS coordinates.
|
|||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['crm', 'account', 'portal'],
|
||||
'demo': ['res_partner_demo.xml'],
|
||||
'demo': ['res_partner_demo.xml', 'crm_lead_demo.xml'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'res_partner_view.xml',
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Demo Leads -->
|
||||
<record id="crm_case_partner_assign_1" model="crm.lead">
|
||||
<field name="type">lead</field>
|
||||
<field name="name">Specifications and price of your phones</field>
|
||||
<field name="contact_name">Steve Martinez</field>
|
||||
<field name="partner_name"></field>
|
||||
<field name="partner_id" ref=""/>
|
||||
<field name="function">Reseller</field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Edinburgh</field>
|
||||
<field name="type_id" ref="crm.type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [ref('crm.categ_oppor1')])]"/>
|
||||
<field name="channel_id" ref="crm.crm_case_channel_email"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="crm.crm_case_section_2"/>
|
||||
<field name="user_id" ref=""/>
|
||||
<field name="stage_id" ref="crm.stage_lead1"/>
|
||||
<field name="description">Hi,
|
||||
|
||||
Please, can you give me more details about your phones, including their specifications and their prices.
|
||||
|
||||
Regards,
|
||||
Steve</field>
|
||||
<field eval="1" name="active"/>
|
||||
<field name="partner_assigned_id" ref="portal.partner_demo_portal"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2012-12-14 13:50+0000\n"
|
||||
"Last-Translator: 盈通 ccdos <ccdos@163.com>\n"
|
||||
"PO-Revision-Date: 2013-07-23 06:22+0000\n"
|
||||
"Last-Translator: fanvil <fanvil@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: 2013-03-16 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16532)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-24 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16700)\n"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.report.assign,delay_close:0
|
||||
|
@ -37,7 +37,7 @@ msgstr "计划收入"
|
|||
msgid ""
|
||||
"Message type: email for email message, notification for system message, "
|
||||
"comment for other messages such as user replies"
|
||||
msgstr ""
|
||||
msgstr "消息类型:Email 用于 邮件消息, 通知用户系统消息,评论用于其他消息,例如用户回复。"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.report.assign,nbr:0
|
||||
|
@ -53,7 +53,7 @@ msgstr "分组..."
|
|||
#. module: crm_partner_assign
|
||||
#: help:crm.lead.forward.to.partner,body:0
|
||||
msgid "Automatically sanitized HTML contents"
|
||||
msgstr ""
|
||||
msgstr "自动整理HTML内容"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead:0
|
||||
|
@ -68,7 +68,7 @@ msgstr "geolocalization定位"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,starred:0
|
||||
msgid "Starred"
|
||||
msgstr ""
|
||||
msgstr "加星号的邮件"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.forward.to.partner:0
|
||||
|
@ -80,7 +80,7 @@ msgstr "正文"
|
|||
msgid ""
|
||||
"Email address of the sender. This field is set when no matching partner is "
|
||||
"found for incoming emails."
|
||||
msgstr ""
|
||||
msgstr "发送者的Email地址。当收取的email没有对应的合作伙伴时,此字段被设置"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.partner.report.assign:0
|
||||
|
@ -111,7 +111,7 @@ msgstr "公司"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,notification_ids:0
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
msgstr "通知"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.report.assign,date_assign:0
|
||||
|
@ -123,7 +123,7 @@ msgstr "业务伙伴日期"
|
|||
#: view:crm.partner.report.assign:0
|
||||
#: view:res.partner:0
|
||||
msgid "Salesperson"
|
||||
msgstr ""
|
||||
msgstr "销售员"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: selection:crm.lead.report.assign,priority:0
|
||||
|
@ -170,7 +170,7 @@ msgstr "指派的geolocalization"
|
|||
#. module: crm_partner_assign
|
||||
#: model:ir.model,name:crm_partner_assign.model_crm_lead_forward_to_partner
|
||||
msgid "Email composition wizard"
|
||||
msgstr ""
|
||||
msgstr "Email撰写向导"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.partner.report.assign,turnover:0
|
||||
|
@ -192,7 +192,7 @@ msgstr "为线索指定一个业务伙伴的概率(0表示没指派)"
|
|||
#. module: crm_partner_assign
|
||||
#: view:res.partner:0
|
||||
msgid "Partner Activation"
|
||||
msgstr ""
|
||||
msgstr "激活合作伙伴"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: selection:crm.lead.forward.to.partner,type:0
|
||||
|
@ -203,7 +203,7 @@ msgstr "系统通知"
|
|||
#: code:addons/crm_partner_assign/wizard/crm_forward_to_partner.py:74
|
||||
#, python-format
|
||||
msgid "Lead forward"
|
||||
msgstr ""
|
||||
msgstr "转发的线索"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.report.assign,probability:0
|
||||
|
@ -284,7 +284,7 @@ msgstr "最低"
|
|||
#. module: crm_partner_assign
|
||||
#: view:crm.partner.report.assign:0
|
||||
msgid "Date Invoice"
|
||||
msgstr ""
|
||||
msgstr "发票排程"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,template_id:0
|
||||
|
@ -309,7 +309,7 @@ msgstr "创建日期"
|
|||
#. module: crm_partner_assign
|
||||
#: model:ir.model,name:crm_partner_assign.model_res_partner_activation
|
||||
msgid "res.partner.activation"
|
||||
msgstr ""
|
||||
msgstr "res.partner.activation"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,parent_id:0
|
||||
|
@ -344,7 +344,7 @@ msgstr "7月"
|
|||
#. module: crm_partner_assign
|
||||
#: view:crm.partner.report.assign:0
|
||||
msgid "Date Review"
|
||||
msgstr ""
|
||||
msgstr "回顾排程"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.report.assign:0
|
||||
|
@ -356,12 +356,12 @@ msgstr "阶段"
|
|||
#: view:crm.lead.report.assign:0
|
||||
#: field:crm.lead.report.assign,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
msgstr "状态"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,to_read:0
|
||||
msgid "To read"
|
||||
msgstr ""
|
||||
msgstr "查看"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: code:addons/crm_partner_assign/wizard/crm_forward_to_partner.py:74
|
||||
|
@ -416,12 +416,12 @@ msgstr "到期天数"
|
|||
#: help:crm.lead.forward.to.partner,notified_partner_ids:0
|
||||
msgid ""
|
||||
"Partners that have a notification pushing this message in their mailboxes"
|
||||
msgstr ""
|
||||
msgstr "推送此通知消息进他们邮箱的合作伙伴"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: selection:crm.lead.forward.to.partner,type:0
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
msgstr "评论"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:res.partner,partner_weight:0
|
||||
|
@ -449,7 +449,7 @@ msgstr "12月"
|
|||
#. module: crm_partner_assign
|
||||
#: help:crm.lead.forward.to.partner,vote_user_ids:0
|
||||
msgid "Users that voted for this message"
|
||||
msgstr ""
|
||||
msgstr "投票给这条消息的用户"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.report.assign:0
|
||||
|
@ -465,13 +465,13 @@ msgstr "开启日期"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,child_ids:0
|
||||
msgid "Child Messages"
|
||||
msgstr ""
|
||||
msgstr "子信息"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.partner.report.assign,date_review:0
|
||||
#: field:res.partner,date_review:0
|
||||
msgid "Latest Partner Review"
|
||||
msgstr ""
|
||||
msgstr "最新合作伙伴评论"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,subject:0
|
||||
|
@ -481,17 +481,17 @@ msgstr "主题"
|
|||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.forward.to.partner:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
msgstr "或"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,body:0
|
||||
msgid "Contents"
|
||||
msgstr ""
|
||||
msgstr "内容"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,vote_user_ids:0
|
||||
msgid "Votes"
|
||||
msgstr ""
|
||||
msgstr "投票"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.report.assign:0
|
||||
|
@ -501,13 +501,13 @@ msgstr "#商机"
|
|||
#. module: crm_partner_assign
|
||||
#: help:crm.lead.forward.to.partner,starred:0
|
||||
msgid "Current user has a starred notification linked to this message"
|
||||
msgstr ""
|
||||
msgstr "当前用户用 星号 提醒关联到这条消息"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.partner.report.assign,date_partnership:0
|
||||
#: field:res.partner,date_partnership:0
|
||||
msgid "Partnership Date"
|
||||
msgstr ""
|
||||
msgstr "合作关系日期"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead:0
|
||||
|
@ -661,7 +661,7 @@ msgstr ""
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.partner.report.assign,period_id:0
|
||||
msgid "Invoice Period"
|
||||
msgstr ""
|
||||
msgstr "发票期间"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: model:ir.model,name:crm_partner_assign.model_res_partner_grade
|
||||
|
@ -682,7 +682,7 @@ msgstr "附件"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,record_name:0
|
||||
msgid "Message Record Name"
|
||||
msgstr ""
|
||||
msgstr "消息记录名称"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:res.partner.activation,sequence:0
|
||||
|
@ -696,7 +696,7 @@ msgstr "序列"
|
|||
msgid ""
|
||||
"Cannot contact geolocation servers. Please make sure that your internet "
|
||||
"connection is up and running (%s)."
|
||||
msgstr ""
|
||||
msgstr "无法连接地理信息服务器。请确保你的互联网链接畅通(%s)。"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: selection:crm.lead.report.assign,month:0
|
||||
|
@ -722,7 +722,7 @@ msgstr "开启"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,subtype_id:0
|
||||
msgid "Subtype"
|
||||
msgstr ""
|
||||
msgstr "子类型"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:res.partner,date_localization:0
|
||||
|
@ -737,12 +737,12 @@ msgstr "当前的"
|
|||
#. module: crm_partner_assign
|
||||
#: model:ir.model,name:crm_partner_assign.model_crm_lead
|
||||
msgid "Lead/Opportunity"
|
||||
msgstr ""
|
||||
msgstr "线索/商机"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,notified_partner_ids:0
|
||||
msgid "Notified partners"
|
||||
msgstr ""
|
||||
msgstr "已通知的合作伙伴"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.forward.to.partner:0
|
||||
|
@ -773,7 +773,7 @@ msgstr "可能收入"
|
|||
#: field:res.partner,activation:0
|
||||
#: view:res.partner.activation:0
|
||||
msgid "Activation"
|
||||
msgstr ""
|
||||
msgstr "激活"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead:0
|
||||
|
@ -784,12 +784,12 @@ msgstr "指定的业务伙伴"
|
|||
#. module: crm_partner_assign
|
||||
#: field:res.partner,grade_id:0
|
||||
msgid "Partner Level"
|
||||
msgstr ""
|
||||
msgstr "合作伙伴级别"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: help:crm.lead.forward.to.partner,to_read:0
|
||||
msgid "Current user has an unread notification linked to this message"
|
||||
msgstr ""
|
||||
msgstr "当前用户有关联到这条消息的未读的提醒"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: selection:crm.lead.report.assign,type:0
|
||||
|
@ -815,7 +815,7 @@ msgstr "名称"
|
|||
#: model:ir.actions.act_window,name:crm_partner_assign.res_partner_activation_act
|
||||
#: model:ir.ui.menu,name:crm_partner_assign.res_partner_activation_config_mi
|
||||
msgid "Partner Activations"
|
||||
msgstr ""
|
||||
msgstr "合作伙伴激活"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: view:crm.lead.report.assign:0
|
||||
|
@ -872,7 +872,7 @@ msgstr "客户关系管理 线索报表"
|
|||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,composition_mode:0
|
||||
msgid "Composition mode"
|
||||
msgstr ""
|
||||
msgstr "写作模式"
|
||||
|
||||
#. module: crm_partner_assign
|
||||
#: field:crm.lead.forward.to.partner,model:0
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
<field name="user_id"/>
|
||||
|
||||
<field string="Timebox" name="timebox_id"/>
|
||||
<button name="prev_timebox" type="object" icon="gtk-go-back" string="Previous" states="draft,pending,open"/>
|
||||
<button name="next_timebox" type="object" icon="gtk-go-forward" string="Next" states="draft,pending,open"/>
|
||||
|
||||
<field name="state"/>
|
||||
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
|
||||
<button name="action_close" states="draft,pending,open" string="Done" type="object" icon="terp-dialog-close" help="For changing to done state"/>
|
||||
<button name="prev_timebox" type="object" string="Previous"/>
|
||||
<button name="next_timebox" type="object" string="Next"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
# Icelandic translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2013-07-10 12:09+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Icelandic <is@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-11 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16696)\n"
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:67
|
||||
#, python-format
|
||||
msgid "Reason:"
|
||||
msgstr "Ástæða:"
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:60
|
||||
#, python-format
|
||||
msgid "The document has been successfully imported!"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:65
|
||||
#, python-format
|
||||
msgid "Sorry, the document could not be imported."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_currency
|
||||
msgid "Currency"
|
||||
msgstr "Gjaldmiðill"
|
||||
|
||||
#. module: edi
|
||||
#. openerp-web
|
||||
#: code:addons/edi/static/src/js/edi.js:71
|
||||
#, python-format
|
||||
msgid "Document Import Notification"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:130
|
||||
#, python-format
|
||||
msgid "Missing application."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:131
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The document you are trying to import requires the OpenERP `%s` application. "
|
||||
"You can install it by connecting as the administrator and opening the "
|
||||
"configuration assistant."
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: code:addons/edi/models/edi.py:47
|
||||
#, python-format
|
||||
msgid "'%s' is an invalid external ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr "Viðskipta aðili"
|
||||
|
||||
#. module: edi
|
||||
#: model:ir.model,name:edi.model_edi_edi
|
||||
msgid "EDI Subsystem"
|
||||
msgstr ""
|
|
@ -22,5 +22,6 @@
|
|||
import email_template
|
||||
import wizard
|
||||
import res_partner
|
||||
import ir_actions
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -59,6 +59,7 @@ campaigns on any OpenERP document.
|
|||
'wizard/email_template_preview_view.xml',
|
||||
'email_template_view.xml',
|
||||
'res_partner_view.xml',
|
||||
'ir_actions_view.xml',
|
||||
'wizard/mail_compose_message_view.xml',
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
.. _changelog:
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
`trunk (saas-2)`
|
||||
----------------
|
||||
|
||||
- ``mail.compose.message``: added support of ``mail_server_id`` from template
|
||||
- Server action update
|
||||
|
||||
- added `email` server action type, now entirely based on email templates.
|
|
@ -0,0 +1,13 @@
|
|||
Email Template module documentation
|
||||
===================================
|
||||
|
||||
Email Template documentation topics
|
||||
'''''''''''''''''''''''''''''''''''
|
||||
|
||||
Changelog
|
||||
'''''''''
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
changelog.rst
|
|
@ -0,0 +1,86 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013 OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
|
||||
class actions_server(osv.Model):
|
||||
""" Add email option in server actions. """
|
||||
_name = 'ir.actions.server'
|
||||
_inherit = ['ir.actions.server']
|
||||
|
||||
def _get_states(self, cr, uid, context=None):
|
||||
res = super(actions_server, self)._get_states(cr, uid, context=context)
|
||||
res.insert(0, ('email', 'Send Email'))
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'email_from': fields.char('From',
|
||||
help="Sender address; define the template to see its value. If not set, the default "
|
||||
"value will be the author's email alias if configured, or email address."),
|
||||
'email_to': fields.char('To (Emails)',
|
||||
help="Comma-separated recipient addresses; define the template to see its value"),
|
||||
'partner_to': fields.char('To (Partners)',
|
||||
help="Comma-separated ids of recipient partners; define the template to see its value"),
|
||||
'subject': fields.char('Subject',
|
||||
help="Email subject; define the template to see its value"),
|
||||
'body_html': fields.text('Body',
|
||||
help="Rich-text/HTML version of the message; define the template to see its value"),
|
||||
'template_id': fields.many2one('email.template', 'Email Template', ondelete='set null',
|
||||
help="Define the email template to use for the email to send.")
|
||||
}
|
||||
|
||||
def on_change_template_id(self, cr, uid, ids, template_id, context=None):
|
||||
""" Render the raw template in the server action fields. """
|
||||
if template_id:
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
|
||||
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
|
||||
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
|
||||
if not values.get('email_from'):
|
||||
return {'warning': {'title': 'Incomplete template', 'message': 'Your template should define email_from'}, 'value': values}
|
||||
else:
|
||||
values = self.default_get(cr, uid, ['subject', 'body_html', 'email_from', 'email_to', 'partner_to'], context=context)
|
||||
|
||||
return {'value': values}
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if values.get('template_id'):
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
|
||||
template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context)
|
||||
values.update(dict((field, template_values[field]) for field in fields if template_values.get(field)))
|
||||
return super(actions_server, self).create(cr, uid, values, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, values, context=None):
|
||||
if values.get('template_id'):
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
|
||||
template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context)
|
||||
values.update(dict((field, template_values[field]) for field in fields if template_values.get(field)))
|
||||
return super(actions_server, self).write(cr, uid, ids, values, context=context)
|
||||
|
||||
def run_action_email(self, cr, uid, action, eval_context=None, context=None):
|
||||
if not action.template_id or not context.get('active_id'):
|
||||
return False
|
||||
self.pool['email.template'].send_mail(cr, uid, action.template_id.id, context.get('active_id'),
|
||||
force_send=False, raise_exception=False, context=context)
|
||||
return False
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="view_server_action_form_template">
|
||||
<field name="name">ir.actions.server.form</field>
|
||||
<field name="model">ir.actions.server</field>
|
||||
<field name="inherit_id" ref="base.view_server_action_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='code']" position="after">
|
||||
<page string="Email" autofocus="autofocus"
|
||||
attrs="{'invisible': [('state', '!=', 'email')]}">
|
||||
<p attrs="{'invisible': [('model_id', '!=', False)]}">
|
||||
Please set the Base Model before setting the action details.
|
||||
</p>
|
||||
<group attrs="{'invisible': [('model_id', '=', False)]}">
|
||||
<field name="template_id"
|
||||
on_change='on_change_template_id(template_id)'
|
||||
domain="[('model_id', '=', model_id)]"
|
||||
attrs="{'required': [('state', '=', 'email')]}"/>
|
||||
<p colspan="2" attrs="{'invisible': [('template_id', '!=', False)]}">
|
||||
Choose a template to display its values.
|
||||
</p>
|
||||
<p colspan="2" attrs="{'invisible': [('template_id', '=', False)]}">
|
||||
The values displayed hereunder are informative. When sending the email, the values
|
||||
will be taken from the email template.
|
||||
</p>
|
||||
</group>
|
||||
<group attrs="{'invisible': ['|', ('model_id', '=', False), ('template_id', '=', False)]}">
|
||||
<label for="email_from"/>
|
||||
<div>
|
||||
<field name="email_from" nolabel="1'" readonly="1"
|
||||
attrs="{'required': [('state', '=', 'email')]}"/>
|
||||
<p attrs="{'invisible': [('email_from', '!=', False)]}">
|
||||
Your template does not defined any email_from. Please update your template.
|
||||
</p>
|
||||
</div>
|
||||
<field name="email_to" readonly="1"/>
|
||||
<field name="partner_to" readonly="1"/>
|
||||
<field name="subject" readonly="1" attrs="{'required': [('state', '=', 'email')]}"/>
|
||||
<field name="body_html" readonly="1" attrs="{'required': [('state', '=', 'email')]}"/>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -18,10 +18,11 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import test_mail
|
||||
from . import test_mail, test_ir_actions
|
||||
|
||||
checks = [
|
||||
test_mail,
|
||||
test_ir_actions,
|
||||
]
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,55 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.base.tests.test_ir_actions import TestServerActionsBase
|
||||
|
||||
|
||||
class TestServerActionsEmail(TestServerActionsBase):
|
||||
|
||||
def test_00_state_email(self):
|
||||
""" Test ir.actions.server email type """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# create email_template
|
||||
template_id = self.registry('email.template').create(cr, uid, {
|
||||
'name': 'TestTemplate',
|
||||
'email_from': 'myself@example.com',
|
||||
'email_to': 'brigitte@example.com',
|
||||
'partner_to': '[%s]' % self.test_partner_id,
|
||||
'model_id': self.res_partner_model_id,
|
||||
'subject': 'About ${object.name}',
|
||||
'body_html': '<p>Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}</p>',
|
||||
})
|
||||
|
||||
self.ir_actions_server.write(cr, uid, self.act_id, {
|
||||
'state': 'email',
|
||||
'template_id': template_id,
|
||||
})
|
||||
run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
|
||||
self.assertFalse(run_res, 'ir_actions_server: email server action correctly finished should return False')
|
||||
|
||||
# check an email is waiting for sending
|
||||
mail_ids = self.registry('mail.mail').search(cr, uid, [('subject', '=', 'About TestingPartner')])
|
||||
self.assertEqual(len(mail_ids), 1, 'ir_actions_server: TODO')
|
||||
# check email content
|
||||
mail = self.registry('mail.mail').browse(cr, uid, mail_ids[0])
|
||||
self.assertEqual(mail.body, '<p>Dear TestingPartner, your parent is False</p>',
|
||||
'ir_actions_server: TODO')
|
|
@ -22,6 +22,7 @@
|
|||
from openerp import tools
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
def _reopen(self, res_id, model):
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
|
@ -34,7 +35,8 @@ def _reopen(self, res_id, model):
|
|||
'context': {
|
||||
'default_model': model,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class mail_compose_message(osv.TransientModel):
|
||||
_inherit = 'mail.compose.message'
|
||||
|
@ -58,7 +60,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
context = {}
|
||||
wizard_context = dict(context)
|
||||
for wizard in self.browse(cr, uid, ids, context=context):
|
||||
if wizard.template_id and not wizard.template_id.user_signature:
|
||||
if wizard.template_id:
|
||||
wizard_context['mail_notify_user_signature'] = False # template user_signature is added when generating body_html
|
||||
if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id:
|
||||
continue
|
||||
|
@ -75,7 +77,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
""" - mass_mailing: we cannot render, so return the template values
|
||||
- normal mode: return rendered values """
|
||||
if template_id and composition_mode == 'mass_mail':
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id']
|
||||
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
|
||||
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
|
||||
elif template_id:
|
||||
|
@ -95,7 +97,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
}
|
||||
values['attachment_ids'].append(ir_attach_obj.create(cr, uid, data_attach, context=context))
|
||||
else:
|
||||
values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids'], context=context)
|
||||
values = self.default_get(cr, uid, ['subject', 'body', 'email_from', 'email_to', 'email_cc', 'partner_to', 'reply_to', 'attachment_ids', 'mail_server_id'], context=context)
|
||||
|
||||
if values.get('body_html'):
|
||||
values['body'] = values.pop('body_html')
|
||||
|
@ -150,7 +152,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
mail.compose.message, transform email_cc and email_to into partner_ids """
|
||||
template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
|
||||
# filter template values
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments']
|
||||
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments', 'mail_server_id']
|
||||
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
|
||||
values['body'] = values.pop('body_html', '')
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import urllib2
|
|||
import simplejson
|
||||
|
||||
|
||||
class google_service(osv.osv):
|
||||
class google_service(osv.osv_memory):
|
||||
_name = 'google.service'
|
||||
|
||||
def generate_refresh_token(self, cr, uid, service, authorization_code, context=None):
|
||||
|
@ -51,10 +51,10 @@ class google_service(osv.osv):
|
|||
content = simplejson.loads(content)
|
||||
return content.get('refresh_token')
|
||||
|
||||
def _get_google_token_uri(self, cr, uid, service, context=None):
|
||||
def _get_google_token_uri(self, cr, uid, service, scope, context=None):
|
||||
ir_config = self.pool['ir.config_parameter']
|
||||
params = {
|
||||
'scope': 'https://www.googleapis.com/auth/drive',
|
||||
'scope': scope,
|
||||
'redirect_uri': ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri'),
|
||||
'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
|
||||
'response_type': 'code',
|
||||
|
|
|
@ -54,58 +54,69 @@ class config(osv.osv):
|
|||
attachment = attach_pool.browse(cr, uid, attach_ids[0], context)
|
||||
url = attachment.url
|
||||
else:
|
||||
url = self.copy_doc(cr, uid, res_id, template_id, name_gdocs, model.model, context)
|
||||
url = self.copy_doc(cr, uid, res_id, template_id, name_gdocs, model.model, context).get('url')
|
||||
return url
|
||||
|
||||
def copy_doc(self, cr, uid, res_id, template_id, name_gdocs, res_model, context=None):
|
||||
def get_access_token(self, cr, uid, scope=None, context=None):
|
||||
ir_config = self.pool['ir.config_parameter']
|
||||
google_drive_refresh_token = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_refresh_token')
|
||||
group_config = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'group_erp_manager')[1]
|
||||
user = self.pool['res.users'].read(cr, uid, uid, "groups_id")
|
||||
if not google_drive_refresh_token:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("You haven't configured 'Authorization Code' generated from google, Please generate and configure it in %(menu:base_setup.menu_general_configuration)s."), context=context)
|
||||
if group_config in user['groups_id']:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("You haven't configured 'Authorization Code' generated from google, Please generate and configure it in %(menu:base_setup.menu_general_configuration)s."), context=context)
|
||||
else:
|
||||
raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))
|
||||
google_drive_client_id = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_client_id')
|
||||
google_drive_client_secret = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_client_secret')
|
||||
google_web_base_url = ir_config.get_param(cr, SUPERUSER_ID, 'web.base.url')
|
||||
|
||||
#For Getting New Access Token With help of old Refresh Token
|
||||
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
|
||||
data = dict(client_id=google_drive_client_id,
|
||||
refresh_token=google_drive_refresh_token,
|
||||
client_secret=google_drive_client_secret,
|
||||
grant_type="refresh_token")
|
||||
|
||||
data = urllib.urlencode(data)
|
||||
data = urllib.urlencode(dict(client_id=google_drive_client_id,
|
||||
refresh_token=google_drive_refresh_token,
|
||||
client_secret=google_drive_client_secret,
|
||||
grant_type="refresh_token",
|
||||
scope=scope or 'https://www.googleapis.com/auth/drive'))
|
||||
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
|
||||
try:
|
||||
req = urllib2.Request('https://accounts.google.com/o/oauth2/token', data, headers)
|
||||
content = urllib2.urlopen(req).read()
|
||||
except urllib2.HTTPError:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during the token generation. Please request again an authorization code in %(menu:base_setup.menu_general_configuration)s."), context=context)
|
||||
if group_config in user['groups_id']:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during the token generation. Please request again an authorization code in %(menu:base_setup.menu_general_configuration)s."), context=context)
|
||||
else:
|
||||
raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))
|
||||
content = json.loads(content)
|
||||
return content.get('access_token')
|
||||
|
||||
def copy_doc(self, cr, uid, res_id, template_id, name_gdocs, res_model, context=None):
|
||||
ir_config = self.pool['ir.config_parameter']
|
||||
google_web_base_url = ir_config.get_param(cr, SUPERUSER_ID, 'web.base.url')
|
||||
access_token = self.get_access_token(cr, uid, context=context)
|
||||
# Copy template in to drive with help of new access token
|
||||
if 'access_token' in content:
|
||||
request_url = "https://www.googleapis.com/drive/v2/files/%s?fields=parents/id&access_token=%s" % (template_id, content['access_token'])
|
||||
try:
|
||||
req = urllib2.Request(request_url, None, headers)
|
||||
parents = urllib2.urlopen(req).read()
|
||||
except urllib2.HTTPError:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("The Google Template cannot be found. Maybe it has been deleted."), context=context)
|
||||
parents_dict = json.loads(parents)
|
||||
request_url = "https://www.googleapis.com/drive/v2/files/%s?fields=parents/id&access_token=%s" % (template_id, access_token)
|
||||
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
|
||||
try:
|
||||
req = urllib2.Request(request_url, None, headers)
|
||||
parents = urllib2.urlopen(req).read()
|
||||
except urllib2.HTTPError:
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _("The Google Template cannot be found. Maybe it has been deleted."), context=context)
|
||||
parents_dict = json.loads(parents)
|
||||
|
||||
record_url = "Click on link to open Record in OpenERP\n %s/?db=%s#id=%s&model=%s" % (google_web_base_url, cr.dbname, res_id, res_model)
|
||||
data = {"title": name_gdocs, "description": record_url, "parents": parents_dict['parents']}
|
||||
request_url = "https://www.googleapis.com/drive/v2/files/%s/copy?access_token=%s" % (template_id, content['access_token'])
|
||||
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||
data_json = json.dumps(data)
|
||||
# resp, content = Http().request(request_url, "POST", data_json, headers)
|
||||
req = urllib2.Request(request_url, data_json, headers)
|
||||
content = urllib2.urlopen(req).read()
|
||||
content = json.loads(content)
|
||||
res = False
|
||||
if 'alternateLink' in content.keys():
|
||||
attach_pool = self.pool.get("ir.attachment")
|
||||
attach_vals = {'res_model': res_model, 'name': name_gdocs, 'res_id': res_id, 'type': 'url', 'url': content['alternateLink']}
|
||||
attach_pool.create(cr, uid, attach_vals)
|
||||
res = content['alternateLink']
|
||||
record_url = "Click on link to open Record in OpenERP\n %s/?db=%s#id=%s&model=%s" % (google_web_base_url, cr.dbname, res_id, res_model)
|
||||
data = {"title": name_gdocs, "description": record_url, "parents": parents_dict['parents']}
|
||||
request_url = "https://www.googleapis.com/drive/v2/files/%s/copy?access_token=%s" % (template_id, access_token)
|
||||
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||
data_json = json.dumps(data)
|
||||
# resp, content = Http().request(request_url, "POST", data_json, headers)
|
||||
req = urllib2.Request(request_url, data_json, headers)
|
||||
content = urllib2.urlopen(req).read()
|
||||
content = json.loads(content)
|
||||
res = {}
|
||||
if content.get('alternateLink'):
|
||||
attach_pool = self.pool.get("ir.attachment")
|
||||
attach_vals = {'res_model': res_model, 'name': name_gdocs, 'res_id': res_id, 'type': 'url', 'url': content['alternateLink']}
|
||||
res['id'] = attach_pool.create(cr, uid, attach_vals)
|
||||
res['url'] = content['alternateLink']
|
||||
return res
|
||||
|
||||
def get_google_drive_config(self, cr, uid, res_model, res_id, context=None):
|
||||
|
@ -166,6 +177,7 @@ class config(osv.osv):
|
|||
'google_drive_resource_id': fields.function(_resource_get, type="char", string='Resource Id'),
|
||||
'google_drive_client_id': fields.function(_client_id_get, type="char", string='Google Client '),
|
||||
'name_template': fields.char('Google Drive Name Pattern', size=64, help='Choose how the new google drive will be named, on google side. Eg. gdoc_%(field_name)s', required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
|
||||
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
|
||||
|
@ -179,6 +191,7 @@ class config(osv.osv):
|
|||
|
||||
_defaults = {
|
||||
'name_template': 'Document %(name)s',
|
||||
'active': True,
|
||||
}
|
||||
|
||||
def _check_model_id(self, cr, uid, ids, context=None):
|
||||
|
@ -191,6 +204,9 @@ class config(osv.osv):
|
|||
(_check_model_id, 'Model of selected filter is not matching with model of current template.', ['model_id', 'filter_id']),
|
||||
]
|
||||
|
||||
def get_google_scope(self):
|
||||
return 'https://www.googleapis.com/auth/drive'
|
||||
|
||||
config()
|
||||
|
||||
|
||||
|
@ -202,7 +218,7 @@ class base_config_settings(osv.osv):
|
|||
'google_drive_uri': fields.char('URI', readonly=True, help="The URL to generate the authorization code from Google"),
|
||||
}
|
||||
_defaults = {
|
||||
'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', context=c),
|
||||
'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', scope=s.pool['google.drive.config'].get_google_scope(), context=c),
|
||||
}
|
||||
|
||||
def set_google_authorization_code(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
<record id="config_google_drive_client_id" model="ir.config_parameter">
|
||||
<field name="key">google_drive_client_id</field>
|
||||
<field name="value">39623646228-eg3ggo3mk6o40m7rguobi3rkl9frh4tb.apps.googleusercontent.com</field>
|
||||
<field name="value">598905559630.apps.googleusercontent.com</field>
|
||||
</record>
|
||||
|
||||
<record id="config_google_drive_client_secret" model="ir.config_parameter">
|
||||
<field name="key">google_drive_client_secret</field>
|
||||
<field name="value">Ul-PtmnSWs3euWs20fdono0e</field>
|
||||
<field name="value">vTmou73c-njP-1qCxm7qx7QE</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -8,20 +8,19 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2013-06-27 16:03+0000\n"
|
||||
"PO-Revision-Date: 2012-12-07 22:47+0000\n"
|
||||
"Last-Translator: Fábio Martinelli - http://zupy.com.br "
|
||||
"<webmaster@guaru.net>\n"
|
||||
"PO-Revision-Date: 2013-07-20 22:32+0000\n"
|
||||
"Last-Translator: Claudio de Araujo Santos <claudioaraujosantos@gmail.com>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-06-28 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16681)\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-22 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16696)\n"
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.ui.menu,name:google_drive.menu_google_drive_config
|
||||
msgid "Google Drive configuration"
|
||||
msgstr ""
|
||||
msgstr "Configuração do Google Drive"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:48
|
||||
|
@ -40,6 +39,13 @@ msgid ""
|
|||
"in your Google Drive and in OpenERP attachment will be named\n"
|
||||
" 'Agrolait_SO0001_Sales'."
|
||||
msgstr ""
|
||||
"O nome do documento em anexo pode usar dados fixos ou variáveis. Para "
|
||||
"distinguir entre documentos\n"
|
||||
" Google Drive, usar palavras fixos e campos. "
|
||||
"Por exemplo, no exemplo acima, se escreveu Agrolait_% (nome) s_Sales\n"
|
||||
" no campo Nome da unidade do Google, o "
|
||||
"documento em seu Google Drive e em OpenERP anexo será nomeado\n"
|
||||
" 'Agrolait_SO0001_Sales \"."
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -47,16 +53,18 @@ msgid ""
|
|||
"- If filter is not specified, link of google document will appear in "
|
||||
"\"More\" option for all users for all opportunities."
|
||||
msgstr ""
|
||||
"- Se o filtro não for especificado, ligação de documento google aparecerá na "
|
||||
"opção \"Mais\" para todos os usuários de todas as oportunidades."
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
msgid "To create a new filter:"
|
||||
msgstr ""
|
||||
msgstr "Para criar um novo filtro:"
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.model,name:google_drive.model_base_config_settings
|
||||
msgid "base.config.settings"
|
||||
msgstr ""
|
||||
msgstr "base.config.settings"
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.actions.act_window,help:google_drive.action_google_drive_users_config
|
||||
|
@ -74,17 +82,30 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Clique para adicionar um novo modelo.\n"
|
||||
" </ P>\n"
|
||||
" <p>\n"
|
||||
" Vincular seus próprios modelos Google Drive para "
|
||||
"qualquer registro de OpenERP. Se você tem documentos específicos que você "
|
||||
"realmente deseja que seu colaborador preencher, por exemplo, usar uma "
|
||||
"planilha para controlar a qualidade do seu produto ou rever a lista de "
|
||||
"entrega para cada ordem em um país estrangeiro, ... É muito fácil de "
|
||||
"gerenciá-los, associá-los a OpenERP e usá-los para colaborar com seus "
|
||||
"empregados.\n"
|
||||
" </ P>\n"
|
||||
" "
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:150
|
||||
#, python-format
|
||||
msgid "Incorrect URL!"
|
||||
msgstr ""
|
||||
msgstr "URL incorreto!"
|
||||
|
||||
#. module: google_drive
|
||||
#: view:base.config.settings:0
|
||||
msgid "Configure your templates"
|
||||
msgstr ""
|
||||
msgstr "Configure seus modelos"
|
||||
|
||||
#. module: google_drive
|
||||
#: help:google.drive.config,name_template:0
|
||||
|
@ -92,6 +113,8 @@ msgid ""
|
|||
"Choose how the new google drive will be named, on google side. Eg. "
|
||||
"gdoc_%(field_name)s"
|
||||
msgstr ""
|
||||
"Escolha como a nova unidade google será nomeado, no lado google. Por "
|
||||
"exemplo. gdoc_% (field_name) s"
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -99,6 +122,8 @@ msgid ""
|
|||
"- Go to the OpenERP document you want to filter. For instance, go to "
|
||||
"Opportunities and search on Sales Department."
|
||||
msgstr ""
|
||||
"- Vá para o documento OpenERP você deseja filtrar. Por exemplo, ir para "
|
||||
"Oportunidades e de pesquisa no Departamento de Vendas."
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -106,6 +131,8 @@ msgid ""
|
|||
"- In this \"Search\" view, select the option \"Save Current Filter\", enter "
|
||||
"the name (Ex: Sales Department)"
|
||||
msgstr ""
|
||||
"- Neste ponto de vista \"Pesquisar\", selecione a opção \"Salvar Filtro "
|
||||
"Atual\", digite o nome (Ex: Departamento de Vendas)"
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -114,6 +141,9 @@ msgid ""
|
|||
"\"More\" options will appear for all users in opportunities of Sales "
|
||||
"Department."
|
||||
msgstr ""
|
||||
"- Se você selecionar \"Compartilhar com todos os usuários\", ligação de "
|
||||
"documento google na opção \"Mais\" será exibido para todos os usuários em "
|
||||
"oportunidades do Departamento de Vendas."
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -122,23 +152,28 @@ msgid ""
|
|||
"\"More\" options will not appear for other users in opportunities of Sales "
|
||||
"Department."
|
||||
msgstr ""
|
||||
"- Se você não selecionar \"Compartilhar com todos os usuários\", link do "
|
||||
"documento google em \"More\" opções não aparecerá para outros usuários em "
|
||||
"oportunidades do Departamento de Vendas."
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:48
|
||||
#, python-format
|
||||
msgid "At least one key cannot be found in your Google Drive name pattern"
|
||||
msgstr ""
|
||||
"Pelo menos uma chave não pode ser encontrado em seu padrão de nome de Google "
|
||||
"Drive"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:150
|
||||
#, python-format
|
||||
msgid "Please enter a valid Google Document URL."
|
||||
msgstr ""
|
||||
msgstr "Por favor insira um URL Documento Google válida."
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,google_drive_client_id:0
|
||||
msgid "Google Client "
|
||||
msgstr ""
|
||||
msgstr "Google Cliente "
|
||||
|
||||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
|
@ -146,43 +181,46 @@ msgid ""
|
|||
"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
|
||||
"a4/edit"
|
||||
msgstr ""
|
||||
"https://docs.google.com/document/d/1vOtpJK9scIQz6taD9tJRIETWbEw3fSiaQHArsJYcu"
|
||||
"a4/edit"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,filter_id:0
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
msgstr "Filtro"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,name_template:0
|
||||
msgid "Google Drive Name Pattern"
|
||||
msgstr ""
|
||||
msgstr "Nome Padrão Google Drive"
|
||||
|
||||
#. module: google_drive
|
||||
#: help:base.config.settings,google_drive_uri:0
|
||||
msgid "The URL to generate the authorization code from Google"
|
||||
msgstr ""
|
||||
msgstr "O URL para gerar o código de autorização do Google"
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.filters,name:google_drive.filter_partner
|
||||
msgid "Customer"
|
||||
msgstr ""
|
||||
msgstr "Cliente"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,google_drive_resource_id:0
|
||||
msgid "Resource Id"
|
||||
msgstr ""
|
||||
msgstr "ID Recurso"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:91
|
||||
#, python-format
|
||||
msgid "The Google Template cannot be found. Maybe it has been deleted."
|
||||
msgstr ""
|
||||
"O modelo do Google não pode ser encontrado. Talvez tenha sido excluído."
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.actions.act_window,name:google_drive.action_google_drive_users_config
|
||||
#: model:ir.ui.menu,name:google_drive.menu_google_drive_model_config
|
||||
msgid "Google Drive Templates"
|
||||
msgstr ""
|
||||
msgstr "Templates do Google Drive"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:81
|
||||
|
@ -191,23 +229,25 @@ msgid ""
|
|||
"Something went wrong during the token generation. Please request again an "
|
||||
"authorization code in %(menu:base_setup.menu_general_configuration)s."
|
||||
msgstr ""
|
||||
"Algo deu errado durante a geração de token. Por favor, solicite novamente um "
|
||||
"código de autorização em%(menu:base_setup.menu_general_configuration)s."
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:124
|
||||
#, python-format
|
||||
msgid "Google Drive Error!"
|
||||
msgstr ""
|
||||
msgstr "Google Drive Error!"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:base.config.settings,google_drive_uri:0
|
||||
msgid "URI"
|
||||
msgstr ""
|
||||
msgstr "URL"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:124
|
||||
#, python-format
|
||||
msgid "Creating google drive may only be done by one at a time."
|
||||
msgstr ""
|
||||
msgstr "Criação de unidade google só pode ser feito por um de cada vez."
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,model:0
|
||||
|
@ -218,38 +258,40 @@ msgstr "Modelo"
|
|||
#. module: google_drive
|
||||
#: view:google.drive.config:0
|
||||
msgid "Google Drive Configuration"
|
||||
msgstr ""
|
||||
msgstr "Configuração do acionamento Google"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,name:0
|
||||
msgid "Template Name"
|
||||
msgstr ""
|
||||
msgstr "Nome do modelo"
|
||||
|
||||
#. module: google_drive
|
||||
#: constraint:google.drive.config:0
|
||||
msgid ""
|
||||
"Model of selected filter is not matching with model of current template."
|
||||
msgstr ""
|
||||
"Modelo de filtro selecionado não está combinando com o modelo do modelo "
|
||||
"atual."
|
||||
|
||||
#. module: google_drive
|
||||
#: field:google.drive.config,google_drive_template_url:0
|
||||
msgid "Template URL"
|
||||
msgstr ""
|
||||
msgstr "Modelo de URL"
|
||||
|
||||
#. module: google_drive
|
||||
#: view:base.config.settings:0
|
||||
msgid "and paste it here"
|
||||
msgstr ""
|
||||
msgstr "e cole-o aqui"
|
||||
|
||||
#. module: google_drive
|
||||
#: field:base.config.settings,google_drive_authorization_code:0
|
||||
msgid "Authorization Code"
|
||||
msgstr ""
|
||||
msgstr "Código de Autorização"
|
||||
|
||||
#. module: google_drive
|
||||
#: model:ir.model,name:google_drive.model_google_drive_config
|
||||
msgid "Google Drive templates config"
|
||||
msgstr ""
|
||||
msgstr "Google Drive templates de configuração"
|
||||
|
||||
#. module: google_drive
|
||||
#: code:addons/google_drive/google_drive.py:64
|
||||
|
@ -258,3 +300,6 @@ msgid ""
|
|||
"You haven't configured 'Authorization Code' generated from google, Please "
|
||||
"generate and configure it in %(menu:base_setup.menu_general_configuration)s."
|
||||
msgstr ""
|
||||
"Você não configurou \"Código de Autorização\" gerado a partir do Google, por "
|
||||
"favor, gerar e configurá-lo em "
|
||||
"%(menu:base_setup.menu_general_configuration)s."
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<field name="model" invisible="1" />
|
||||
<group>
|
||||
<field name="name" />
|
||||
<field name="active" />
|
||||
<field name="model_id" on_change="onchange_model_id(model_id)" />
|
||||
<label for='filter_id' />
|
||||
<div>
|
||||
|
@ -54,7 +55,7 @@
|
|||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='action_google_drive_users_config'>
|
||||
<field name='name'>Google Drive Templates</field>
|
||||
<field name='name'>Templates</field>
|
||||
<field name='res_model'>google.drive.config</field>
|
||||
<field name='type'>ir.actions.act_window</field>
|
||||
<field name='view_type'>form</field>
|
||||
|
@ -87,7 +88,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name='Google Drive configuration' id='menu_google_drive_config' parent='base.menu_administration' />
|
||||
<menuitem name='Google Drive' id='menu_google_drive_config' parent='base.menu_administration' />
|
||||
<menuitem id='menu_google_drive_model_config' parent='menu_google_drive_config' action='action_google_drive_users_config' />
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -29,19 +29,24 @@ openerp.google_drive = function (instance, m) {
|
|||
ds.call('get_google_drive_config', [view.dataset.model, res_id, context]).done(function (r) {
|
||||
if (!_.isEmpty(r)) {
|
||||
_.each(r, function (res) {
|
||||
var g_item = _.indexOf(_.pluck(self.items.other, 'label'), res.name);
|
||||
if (g_item !== -1) {
|
||||
self.items.other.splice(g_item, 1);
|
||||
var already_there = false;
|
||||
for (var i = 0;i < self.items.other.length;i++){
|
||||
if (self.items.other[i].classname === "oe_share_gdoc" && self.items.other[i].label.indexOf(res.name) > -1){
|
||||
already_there = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!already_there){
|
||||
self.add_items('other', [{
|
||||
label: res.name+ '<img style="position:absolute;right:5px;height:20px;width:20px;" title="Google Drive" src="google_drive/static/src/img/drive_icon.png"/>',
|
||||
config_id: res.id,
|
||||
res_id: res_id,
|
||||
res_model: view.dataset.model,
|
||||
callback: self.on_google_doc,
|
||||
classname: 'oe_share_gdoc'
|
||||
},
|
||||
]);
|
||||
}
|
||||
self.add_items('other', [{
|
||||
label: res.name+ '<img style="position:absolute;right:5px;height:20px;width:20px;" title="Google Drive" src="google_drive/static/src/img/drive_icon.png"/>',
|
||||
config_id: res.id,
|
||||
res_id: res_id,
|
||||
res_model: view.dataset.model,
|
||||
callback: self.on_google_doc,
|
||||
classname: 'oe_share_gdoc'
|
||||
},
|
||||
]);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import google_spreadsheet
|
|
@ -0,0 +1,43 @@
|
|||
# -*- 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
||||
{
|
||||
'name': 'Google Spreadsheet',
|
||||
'version': '1.0',
|
||||
'category': 'Tools',
|
||||
'description': """
|
||||
The module adds the possibility to display data from OpenERP in Google Spreadsheets in real time.
|
||||
========================================
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['board', 'google_drive'],
|
||||
'js': [
|
||||
'static/src/js/search.js',
|
||||
],
|
||||
'qweb': ['static/src/xml/*.xml'],
|
||||
'data': ['google_spreadsheet_view.xml', 'google_spreadsheet_data.xml'],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,109 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2012 OpenERP SA (<http://www.openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import simplejson
|
||||
from lxml import etree
|
||||
import re
|
||||
import requests
|
||||
|
||||
from openerp.osv import osv
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
|
||||
class config(osv.osv):
|
||||
_inherit = 'google.drive.config'
|
||||
|
||||
def get_google_scope(self):
|
||||
scope = super(config, self).get_google_scope()
|
||||
return '%s https://spreadsheets.google.com/feeds' % scope
|
||||
|
||||
def write_config_formula(self, cr, uid, attachment_id, spreadsheet_key, model, domain, groupbys, view_id, context=None):
|
||||
access_token = self.get_access_token(cr, uid, scope='https://spreadsheets.google.com/feeds', context=context)
|
||||
|
||||
fields = self.pool.get(model).fields_view_get(cr, uid, view_id=view_id, view_type='tree')
|
||||
doc = etree.XML(fields.get('arch'))
|
||||
display_fields = []
|
||||
for node in doc.xpath("//field"):
|
||||
if node.get('modifiers'):
|
||||
modifiers = simplejson.loads(node.get('modifiers'))
|
||||
if not modifiers.get('invisible') and not modifiers.get('tree_invisible'):
|
||||
display_fields.append(node.get('name'))
|
||||
fields = " ".join(display_fields)
|
||||
domain = domain.replace("'", r"\'").replace('"', "'")
|
||||
if groupbys:
|
||||
fields = "%s %s" % (groupbys, fields)
|
||||
formula = '=oe_read_group("%s";"%s";"%s";"%s")' % (model, fields, groupbys, domain)
|
||||
else:
|
||||
formula = '=oe_browse("%s";"%s";"%s")' % (model, fields, domain)
|
||||
url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
|
||||
dbname = cr.dbname
|
||||
user = self.pool['res.users'].read(cr, uid, uid, ['login', 'password'], context=context)
|
||||
username = user['login']
|
||||
password = user['password']
|
||||
if self.pool['ir.module.module'].search_count(cr, SUPERUSER_ID, ['&', ('name', '=', 'auth_crypt'), ('state', '=', 'installed')]) == 1:
|
||||
config_formula = '=oe_settings("%s";"%s")' % (url, dbname)
|
||||
else:
|
||||
config_formula = '=oe_settings("%s";"%s";"%s";"%s")' % (url, dbname, username, password)
|
||||
request = '''<feed xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:batch="http://schemas.google.com/gdata/batch"
|
||||
xmlns:gs="http://schemas.google.com/spreadsheets/2006">
|
||||
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full</id>
|
||||
<entry>
|
||||
<batch:id>A1</batch:id>
|
||||
<batch:operation type="update"/>
|
||||
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R1C1</id>
|
||||
<link rel="edit" type="application/atom+xml"
|
||||
href="https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R1C1"/>
|
||||
<gs:cell row="1" col="1" inputValue="%s"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<batch:id>A2</batch:id>
|
||||
<batch:operation type="update"/>
|
||||
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R60C15</id>
|
||||
<link rel="edit" type="application/atom+xml"
|
||||
href="https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R60C15"/>
|
||||
<gs:cell row="60" col="15" inputValue="%s"/>
|
||||
</entry>
|
||||
</feed>''' % (spreadsheet_key, spreadsheet_key, spreadsheet_key, formula.replace('"', '"'), spreadsheet_key, spreadsheet_key, config_formula.replace('"', '"'))
|
||||
|
||||
requests.post('https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?v=3&access_token=%s' % (spreadsheet_key, access_token), data=request, headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
|
||||
|
||||
description = '''
|
||||
formula: %s
|
||||
''' % formula
|
||||
if attachment_id:
|
||||
self.pool['ir.attachment'].write(cr, uid, attachment_id, {'description': description}, context=context)
|
||||
return True
|
||||
|
||||
def set_spreadsheet(self, cr, uid, model, domain, groupbys, view_id, context=None):
|
||||
try:
|
||||
config_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'google_spreadsheet', 'google_spreadsheet_template')[1]
|
||||
except ValueError:
|
||||
raise
|
||||
config = self.browse(cr, uid, config_id, context=context)
|
||||
title = 'Spreadsheet %s' % model
|
||||
res = self.copy_doc(cr, uid, False, config.google_drive_resource_id, title, model, context=context)
|
||||
|
||||
mo = re.search("(key=|/d/)([A-Za-z0-9-_]+)", res['url'])
|
||||
if mo:
|
||||
key = mo.group(2)
|
||||
|
||||
self.write_config_formula(cr, uid, res.get('id'), key, model, domain, groupbys, view_id, context=context)
|
||||
return res
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="google_spreadsheet_template" model="google.drive.config">
|
||||
<field name="name">Base Spreadsheet Template</field>
|
||||
<field name="model_id" ref="base.model_res_partner"/>
|
||||
<field name="google_drive_template_url">https://docs.google.com/spreadsheet/ccc?key=0ApGVjjwUC-ygdDZ0TG5EQnRlLVFQNlFGdFN5b1ZrY1E</field>
|
||||
<field name="name_template">Reporting %(name)s</field>
|
||||
<field name="active" eval="0" />
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- add google drive config field in user form -->
|
||||
|
||||
<record model="ir.ui.view" id="view_ir_attachment_google_spreadsheet_tree">
|
||||
<field name="name">ir.attachment.google.spreadsheet.tree</field>
|
||||
<field name="model">ir.attachment</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Google Spreadsheets" version="7.0">
|
||||
<field name="name" string="Name"/>
|
||||
<field name="url" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_ir_attachment_google_spreadsheet_form">
|
||||
<field name="name">ir.attachment.google.spreadsheet.form</field>
|
||||
<field name="model">ir.attachment</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Google Spreadsheets" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" string="Name"/>
|
||||
<field name="url" widget="url"/>
|
||||
</group>
|
||||
<group colspan="2">
|
||||
<label for="description" colspan="2"/>
|
||||
<field name="description" nolabel="1" colspan="2"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_ir_attachment_google_spreadsheet_tree" model="ir.actions.act_window">
|
||||
<field name="name">Google Spreadsheets</field>
|
||||
<field name="res_model">ir.attachment</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="domain">[('url', 'like', '/spreadsheet/')]</field>
|
||||
<field name="help">Google Spreadsheets</field>
|
||||
</record>
|
||||
|
||||
<record id="action_ir_attachment_google_spreadsheet_tree_view" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_ir_attachment_google_spreadsheet_tree"/>
|
||||
<field name="act_window_id" ref="action_ir_attachment_google_spreadsheet_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="action_ir_attachment_google_spreadsheet_form_view" model="ir.actions.act_window.view">
|
||||
<field eval="2" name="sequence"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_ir_attachment_google_spreadsheet_form"/>
|
||||
<field name="act_window_id" ref="action_ir_attachment_google_spreadsheet_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_reporting_dashboard_google_spreadsheets" parent="base.menu_reporting_dashboard" action="action_ir_attachment_google_spreadsheet_tree"/>
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,42 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * google_spreadsheet
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 8.0alpha1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-25 12:39+0000\n"
|
||||
"PO-Revision-Date: 2013-07-25 12:39+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: google_spreadsheet
|
||||
#: model:ir.actions.act_window,help:google_spreadsheet.action_ir_attachment_google_spreadsheet_tree
|
||||
#: model:ir.actions.act_window,name:google_spreadsheet.action_ir_attachment_google_spreadsheet_tree
|
||||
#: view:ir.attachment:0
|
||||
#: model:ir.ui.menu,name:google_spreadsheet.menu_reporting_dashboard_google_spreadsheets
|
||||
msgid "Google Spreadsheets"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_spreadsheet
|
||||
#. openerp-web
|
||||
#: code:addons/google_spreadsheet/static/src/xml/addtospreadsheet.xml:3
|
||||
#, python-format
|
||||
msgid "Add to Google Spreadsheet"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_spreadsheet
|
||||
#: view:ir.attachment:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_spreadsheet
|
||||
#: model:ir.model,name:google_spreadsheet.model_google_drive_config
|
||||
msgid "Google Drive templates config"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
openerp.google_spreadsheet = function(instance) {
|
||||
var _t = instance.web._t;
|
||||
instance.web.FormView.include({
|
||||
on_processed_onchange: function(result, processed) {
|
||||
var self = this;
|
||||
|
||||
var fields = self.fields;
|
||||
_(result.selection).each(function (selection, fieldname) {
|
||||
var field = fields[fieldname];
|
||||
if (!field) { return; }
|
||||
field.field.selection = selection;
|
||||
field.values = selection;
|
||||
field.renderElement();
|
||||
});
|
||||
return this._super(result, processed);
|
||||
},
|
||||
});
|
||||
instance.board.AddToGoogleSpreadsheet = instance.web.search.Input.extend({
|
||||
template: 'SearchView.addtogooglespreadsheet',
|
||||
_in_drawer: true,
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.$el.on('click', 'h4', function(){
|
||||
var view = self.view;
|
||||
var data = view.build_search_data();
|
||||
var model = view.model;
|
||||
var list_view = self.view.getParent().views['list'];
|
||||
var view_id = list_view ? list_view.view_id : false;
|
||||
var context = new instance.web.CompoundContext(view.dataset.get_context() || []);
|
||||
var domain = new instance.web.CompoundDomain(view.dataset.get_domain() || []);
|
||||
_.each(data.contexts, context.add, context);
|
||||
_.each(data.domains, domain.add, domain);
|
||||
domain = JSON.stringify(domain.eval());
|
||||
var groupbys = instance.web.pyeval.eval('groupbys', data.groupbys).join(" ");
|
||||
var view_id = view_id;
|
||||
var ds = new instance.web.DataSet(self, 'google.drive.config');
|
||||
ds.call('set_spreadsheet', [model, domain, groupbys, view_id]).done(function (res) {
|
||||
if (res['url']){
|
||||
window.open(res['url'], '_blank');
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
instance.web.SearchView.include({
|
||||
add_common_inputs: function() {
|
||||
this._super();
|
||||
var vm = this.getParent().getParent();
|
||||
if (vm.inner_action && vm.inner_action.views) {
|
||||
(new instance.board.AddToGoogleSpreadsheet(this));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div t-name="SearchView.addtogooglespreadsheet" class="oe_searchview_dashboard">
|
||||
<h4>Add to Google Spreadsheet</h4>
|
||||
</div>
|
||||
</template>
|
|
@ -51,9 +51,9 @@ class hr_employee_category(osv.osv):
|
|||
_name = "hr.employee.category"
|
||||
_description = "Employee Category"
|
||||
_columns = {
|
||||
'name': fields.char("Category", size=64, required=True),
|
||||
'name': fields.char("Employee Tag", size=64, required=True),
|
||||
'complete_name': fields.function(_name_get_fnc, type="char", string='Name'),
|
||||
'parent_id': fields.many2one('hr.employee.category', 'Parent Category', select=True),
|
||||
'parent_id': fields.many2one('hr.employee.category', 'Parent Employee Tag', select=True),
|
||||
'child_ids': fields.one2many('hr.employee.category', 'parent_id', 'Child Categories'),
|
||||
'employee_ids': fields.many2many('hr.employee', 'employee_category_rel', 'category_id', 'emp_id', 'Employees'),
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class hr_job(osv.osv):
|
|||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('name_company_uniq', 'unique(name, company_id)', 'The name of the job position must be unique per company!'),
|
||||
('name_company_uniq', 'unique(name, company_id, department_id)', 'The name of the job position must be unique per department in company!'),
|
||||
]
|
||||
|
||||
|
||||
|
@ -156,6 +156,8 @@ class hr_employee(osv.osv):
|
|||
_inherits = {'resource.resource': "resource_id"}
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
_mail_post_access = 'read'
|
||||
|
||||
def _get_image(self, cr, uid, ids, name, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -324,22 +326,6 @@ class hr_employee(osv.osv):
|
|||
(_check_recursion, 'Error! You cannot create recursive hierarchy of Employee(s).', ['parent_id']),
|
||||
]
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Mail gateway
|
||||
# ---------------------------------------------------
|
||||
|
||||
def check_mail_message_access(self, cr, uid, mids, operation, model_obj=None, context=None):
|
||||
""" mail.message document permission rule: can post a new message if can read
|
||||
because of portal document. """
|
||||
if not model_obj:
|
||||
model_obj = self
|
||||
employee_ids = model_obj.search(cr, uid, [('user_id', '=', uid)], context=context)
|
||||
if employee_ids and operation == 'create':
|
||||
model_obj.check_access_rights(cr, uid, 'read')
|
||||
model_obj.check_access_rule(cr, uid, mids, 'read', context=context)
|
||||
else:
|
||||
return super(hr_employee, self).check_mail_message_access(cr, uid, mids, operation, model_obj=model_obj, context=context)
|
||||
|
||||
|
||||
class hr_department(osv.osv):
|
||||
_description = "Department"
|
||||
|
|
|
@ -17,7 +17,7 @@ Get all your HR operations managed easily: knowledge sharing, recruitments, appr
|
|||
Each need is provided by a specific app that you activate on demand.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=hr" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -79,7 +79,7 @@ class hr_holidays_status(osv.osv):
|
|||
'categ_id': fields.many2one('crm.meeting.type', 'Meeting Type',
|
||||
help='Once a leave is validated, OpenERP will create a corresponding meeting of this type in the calendar.'),
|
||||
'color_name': fields.selection([('red', 'Red'),('blue','Blue'), ('lightgreen', 'Light Green'), ('lightblue','Light Blue'), ('lightyellow', 'Light Yellow'), ('magenta', 'Magenta'),('lightcyan', 'Light Cyan'),('black', 'Black'),('lightpink', 'Light Pink'),('brown', 'Brown'),('violet', 'Violet'),('lightcoral', 'Light Coral'),('lightsalmon', 'Light Salmon'),('lavender', 'Lavender'),('wheat', 'Wheat'),('ivory', 'Ivory')],'Color in Report', required=True, help='This color will be used in the leaves summary located in Reporting\Leaves by Department.'),
|
||||
'limit': fields.boolean('Allow to Override Limit', help='If you select this check box, the system allows the employees to take more leaves than the available ones for this type and take them into account for the "Remaining Legal Leaves" defined on the employee form.'),
|
||||
'limit': fields.boolean('Allow to Override Limit', help='If you select this check box, the system allows the employees to take more leaves than the available ones for this type and will not take them into account for the "Remaining Legal Leaves" defined on the employee form.'),
|
||||
'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the leave type without removing it."),
|
||||
'max_leaves': fields.function(_user_left_days, string='Maximum Allowed', help='This value is given by the sum of all holidays requests with a positive value.', multi='user_left_days'),
|
||||
'leaves_taken': fields.function(_user_left_days, string='Leaves Already Taken', help='This value is given by the sum of all holidays requests with a negative value.', multi='user_left_days'),
|
||||
|
|
|
@ -322,7 +322,7 @@
|
|||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Other Information">
|
||||
<page string="Accounting Information">
|
||||
<group>
|
||||
<group string="Miscellaneous">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
new_id = self.create(cr, uid, {'account_id': ref('account.analytic_nebula'),'analytic_amount': 7.0,
|
||||
'date': (datetime.now()+timedelta(1)).strftime('%Y-%m-%d %H:%M:%S') ,
|
||||
'date_start': time.strftime('%Y-%m-%d %H:%M:%S'), 'info': 'Create Yaml for hr module',
|
||||
'name': 'Quentin Paolino', 'server_date': time.strftime('%Y-%m-%d %H:%M:%S'), 'state': 'action'})
|
||||
'name': 'Quentin Paolino', 'server_date': time.strftime('%Y-%m-%d %H:%M:%S'), 'state': 'present'})
|
||||
self.sign_out_result(cr, uid, [new_id], context)
|
||||
-
|
||||
My work for this project "Sednacom" is over and I stop working by clicking on "Stop Work" button of this wizard.
|
||||
|
|
|
@ -32,8 +32,8 @@ class hr_so_project(osv.osv_memory):
|
|||
'date_start': fields.datetime('Starting Date', readonly=True),
|
||||
'date': fields.datetime('Closing Date'),
|
||||
'analytic_amount': fields.float('Minimum Analytic Amount'),
|
||||
'name': fields.char('Employees name', size=32, required=True, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='char', required=True, readonly=True),
|
||||
'name': fields.char('Employee\'s Name', size=32, required=True, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='selection', selection=[('present', 'Present'), ('absent', 'Absent')], required=True, readonly=True),
|
||||
'server_date': fields.datetime('Current Date', required=True, readonly=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Employee ID')
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ class hr_si_project(osv.osv_memory):
|
|||
_name = 'hr.sign.in.project'
|
||||
_description = 'Sign In By Project'
|
||||
_columns = {
|
||||
'name': fields.char('Employees name', size=32, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='char', required=True, readonly=True),
|
||||
'name': fields.char('Employee\'s Name', size=32, readonly=True),
|
||||
'state': fields.related('emp_id', 'state', string='Current Status', type='selection', selection=[('present', 'Present'), ('absent', 'Absent')], required=True, readonly=True),
|
||||
'date': fields.datetime('Starting Date'),
|
||||
'server_date': fields.datetime('Current Date', readonly=True),
|
||||
'emp_id': fields.many2one('hr.employee', 'Employee ID')
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
</record>
|
||||
|
||||
<record id="action_hr_timesheet_sign_in" model="ir.actions.act_window">
|
||||
<field name="name">Sign in / Sign out by project</field>
|
||||
<field name="name">Sign in / Sign out by Project</field>
|
||||
<field name="res_model">hr.sign.in.project</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
|
@ -67,7 +67,7 @@
|
|||
<field name="account_id" colspan="2"/>
|
||||
<field name="info" colspan="2"/>
|
||||
<field name="date"/>
|
||||
<label string="(Keep empty for current_time)" colspan="2"/>
|
||||
<label string="(Keep empty for current time)" colspan="2"/>
|
||||
<field name="analytic_amount"/>
|
||||
</group>
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
|||
</record>
|
||||
|
||||
<record id="action_hr_timesheet_sign_out" model="ir.actions.act_window">
|
||||
<field name="name">Sign in / Sign out by project</field>
|
||||
<field name="name">Sign in / Sign out by Project</field>
|
||||
<field name="res_model">hr.sign.out.project</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
|
|
|
@ -101,17 +101,19 @@ class LongPollingController(http.Controller):
|
|||
raise Exception("Not usable in a server not running gevent")
|
||||
from openerp.addons.im.watcher import ImWatcher
|
||||
if db is not None:
|
||||
request.session.authenticate(db=db, uid=uid, password=password)
|
||||
openerp.service.security.check(db, uid, password)
|
||||
else:
|
||||
request.session.authenticate(db=request.session._db, uid=request.session._uid, password=request.session._password)
|
||||
uid = request.session.uid
|
||||
db = request.session.db
|
||||
|
||||
with request.registry.cursor() as cr:
|
||||
request.registry.get('im.user').im_connect(cr, request.uid, uuid=uuid, context=request.context)
|
||||
my_id = request.registry.get('im.user').get_by_user_id(cr, request.uid, uuid or request.session._uid, request.context)["id"]
|
||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||
with registry.cursor() as cr:
|
||||
registry.get('im.user').im_connect(cr, uid, uuid=uuid, context=request.context)
|
||||
my_id = registry.get('im.user').get_by_user_id(cr, uid, uuid or uid, request.context)["id"]
|
||||
num = 0
|
||||
while True:
|
||||
with request.registry.cursor() as cr:
|
||||
res = request.registry.get('im.message').get_messages(cr, request.uid, last, users_watch, uuid=uuid, context=request.context)
|
||||
with registry.cursor() as cr:
|
||||
res = registry.get('im.message').get_messages(cr, uid, last, users_watch, uuid=uuid, context=request.context)
|
||||
if num >= 1 or len(res["res"]) > 0:
|
||||
return res
|
||||
last = res["last"]
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
# 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
|
||||
# it under the terms of the GNU Affero General anonymous 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.
|
||||
# GNU Affero General anonymous License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# You should have received a copy of the GNU Affero General anonymous License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
@ -37,36 +37,45 @@ env.filters["json"] = json.dumps
|
|||
|
||||
class LiveChatController(http.Controller):
|
||||
|
||||
@http.route('/im_livechat/loader')
|
||||
def _auth(self, db):
|
||||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, "anonymous", "anonymous", None])
|
||||
return reg, uid
|
||||
|
||||
@http.route('/im_livechat/loader', auth="none")
|
||||
def loader(self, **kwargs):
|
||||
p = json.loads(kwargs["p"])
|
||||
db = p["db"]
|
||||
channel = p["channel"]
|
||||
user_name = p.get("user_name", None)
|
||||
request.session.authenticate(db=db, login="public", password="public")
|
||||
info = request.session.model('im_livechat.channel').get_info_for_chat_src(channel)
|
||||
info["db"] = db
|
||||
info["channel"] = channel
|
||||
info["userName"] = user_name
|
||||
return request.make_response(env.get_template("loader.js").render(info),
|
||||
headers=[('Content-Type', "text/javascript")])
|
||||
|
||||
@http.route('/im_livechat/web_page')
|
||||
reg, uid = self._auth(db)
|
||||
with reg.cursor() as cr:
|
||||
info = reg.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel)
|
||||
info["db"] = db
|
||||
info["channel"] = channel
|
||||
info["userName"] = user_name
|
||||
return request.make_response(env.get_template("loader.js").render(info),
|
||||
headers=[('Content-Type', "text/javascript")])
|
||||
|
||||
@http.route('/im_livechat/web_page', auth="none")
|
||||
def web_page(self, **kwargs):
|
||||
p = json.loads(kwargs["p"])
|
||||
db = p["db"]
|
||||
channel = p["channel"]
|
||||
request.session.authenticate(db=db, login="public", password="public")
|
||||
script = request.session.model('im_livechat.channel').read(channel, ["script"])["script"]
|
||||
info = request.session.model('im_livechat.channel').get_info_for_chat_src(channel)
|
||||
info["script"] = script
|
||||
return request.make_response(env.get_template("web_page.html").render(info),
|
||||
headers=[('Content-Type', "text/html")])
|
||||
reg, uid = self._auth(db)
|
||||
with reg.cursor() as cr:
|
||||
script = reg.get('im_livechat.channel').read(cr, uid, channel, ["script"])["script"]
|
||||
info = reg.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel)
|
||||
info["script"] = script
|
||||
return request.make_response(env.get_template("web_page.html").render(info),
|
||||
headers=[('Content-Type', "text/html")])
|
||||
|
||||
@http.route('/im_livechat/available', type='json')
|
||||
@http.route('/im_livechat/available', type='json', auth="none")
|
||||
def available(self, db, channel):
|
||||
request.session.authenticate(db=db, login="public", password="public")
|
||||
return request.session.model('im_livechat.channel').get_available_user(channel) > 0
|
||||
reg, uid = self._auth(db)
|
||||
with reg.cursor() as cr:
|
||||
return reg.get('im_livechat.channel').get_available_user(cr, uid, channel) > 0
|
||||
|
||||
class im_livechat_channel(osv.osv):
|
||||
_name = 'im_livechat.channel'
|
||||
|
|
|
@ -135,11 +135,47 @@
|
|||
<record model="account.account.template" id="a189">
|
||||
<field name="name">Tax Receivable</field>
|
||||
<field name="code">189</field>
|
||||
<field name="type">other</field>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="account.data_account_type_asset"/>
|
||||
<field name="reconcile" eval="False"/>
|
||||
<field name="parent_id" ref="a10"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="a189100">
|
||||
<field name="name">Purchase Tax Receivable</field>
|
||||
<field name="code">189100</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="reconcile" eval="True"/>
|
||||
<field name="parent_id" ref="a189"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="a189200">
|
||||
<field name="name">VAT Receivable</field>
|
||||
<field name="code">189200</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="reconcile" eval="True"/>
|
||||
<field name="parent_id" ref="a189"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="a189300">
|
||||
<field name="name">Service Tax Receivable</field>
|
||||
<field name="code">189300</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="reconcile" eval="True"/>
|
||||
<field name="parent_id" ref="a189"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="a189400">
|
||||
<field name="name">Exice Duty Receivable</field>
|
||||
<field name="code">189400</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="reconcile" eval="True"/>
|
||||
<field name="parent_id" ref="a189"/>
|
||||
</record>
|
||||
|
||||
<!-- Liabilities -->
|
||||
|
||||
<record model="account.account.template" id="a20">
|
||||
|
|
|
@ -2,269 +2,403 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!-- Taxes Sale Tax -->
|
||||
|
||||
|
||||
<record id="sales_private" model="account.tax.template">
|
||||
<field name="name">Sale Tax-15%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
<field name="name">Sales Tax 15%</field>
|
||||
<field name="description">Sales Tax 15%</field>
|
||||
<field name="amount">0.15</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2161"/>
|
||||
<field name="account_paid_id" ref="a2161"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="account_paid_id" ref="a2161"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale15"/>
|
||||
<field name="tax_code_id" ref="vat_code_rec_sale15"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale15"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_rec_sale15"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="sales_private_main" model="account.tax.template">
|
||||
<field name="name">Sale Tax-12%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
<field name="name">Sales Tax 12%</field>
|
||||
<field name="description">Sales Tax 12%</field>
|
||||
<field name="amount">0.12</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2161"/>
|
||||
<field name="account_paid_id" ref="a2161"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="account_paid_id" ref="a2161"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale12"/>
|
||||
<field name="tax_code_id" ref="vat_code_rec_sale12"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale12"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_rec_sale12"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="sales_private_main_4" model="account.tax.template">
|
||||
<field name="name">Sale Tax-4%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
<field name="name">Sales Tax 4%</field>
|
||||
<field name="description">Sales Tax 4%</field>
|
||||
<field name="amount">0.04</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2161"/>
|
||||
<field name="account_paid_id" ref="a2161"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale4"/>
|
||||
<field name="tax_code_id" ref="vat_code_rec_sale4"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale4"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_rec_sale4"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<!-- Purchase tax -->
|
||||
|
||||
|
||||
<record id="purchase_tax_private" model="account.tax.template">
|
||||
<field name="name">Purchase Tax-15%</field>
|
||||
<field name="name">Purchase Tax 15%</field>
|
||||
<field name="description">Purchase Tax 15%</field>
|
||||
<field name="account_collected_id" ref="a189"/>
|
||||
<field name="account_paid_id" ref="a189"/>
|
||||
<field name="price_include" eval="0"/>
|
||||
<field name="account_paid_id" ref="a189"/>
|
||||
<field name="amount">0.15</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_purchase"/>
|
||||
<field name="tax_code_id" ref="vat_code_payable"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_purchase"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_payable"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_pur15"/>
|
||||
<field name="tax_code_id" ref="vat_code_pay_pur4"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_pur15"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_pay_pur4"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- vat -->
|
||||
|
||||
<record id="vat_private_main" model="account.tax.template">
|
||||
<field name="name">VAT-5%(4% VAT+1% Add. Tax.)</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
|
||||
<record id="vat_private_out_vat5" model="account.tax.template">
|
||||
<field name="name">Output VAT 5% (VAT 4% + Add. VAT 1%)</field>
|
||||
<field name="description">Output VAT 5%</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.04</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sal_vat5"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_vat5"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sal_vat5"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_vat5"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_in_vat5" model="account.tax.template">
|
||||
<field name="name">Input VAT 5% (VAT 4% + Add. VAT 1%)</field>
|
||||
<field name="description">Input VAT 5%</field>
|
||||
<field name="amount">0.05</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="base_sign">1</field>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="tax_sign">1</field>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_base_sign">1</field>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_tax_sign">1</field>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="a189200"/>
|
||||
<field name="account_paid_id" ref="a189200"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_vat5"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_vat5"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_vat5"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_vat5"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_main_tax" model="account.tax.template">
|
||||
<field name="name">VAT-15%(12.5% VAT+2.5% Add. Tax.)</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
|
||||
<record id="vat_private_in_vat15" model="account.tax.template">
|
||||
<field name="name">Input VAT 15% (VAT 12.5% + Add. VAT 2.5%)</field>
|
||||
<field name="description">Input VAT 15%</field>
|
||||
<field name="amount">0.15</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="base_sign">1</field>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="tax_sign">1</field>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_base_sign">1</field>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_tax_sign">1</field>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="a189200"/>
|
||||
<field name="account_paid_id" ref="a189200"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_vat15"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_vat15"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_vat15"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_vat15"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_tax" model="account.tax.template">
|
||||
<field name="name">VAT-8%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
|
||||
<record id="vat_private_out_vat15" model="account.tax.template">
|
||||
<field name="name">Output VAT 15% (VAT 12.5% + Add. VAT 2.5%)</field>
|
||||
<field name="description">Output VAT 15%</field>
|
||||
<field name="amount">0.15</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sal_vat15"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_vat15"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sal_vat15"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_vat15"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_in_vat8" model="account.tax.template">
|
||||
<field name="name">Input VAT 8%</field>
|
||||
<field name="description">Input VAT 8%</field>
|
||||
<field name="amount">0.08</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="a189200"/>
|
||||
<field name="account_paid_id" ref="a189200"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_vat8"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_vat8"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_vat8"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_vat8"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_tax_10" model="account.tax.template">
|
||||
<field name="name">VAT-10%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
<record id="vat_private_out_vat8" model="account.tax.template">
|
||||
<field name="name">Output VAT 8%</field>
|
||||
<field name="description">Output VAT 8%</field>
|
||||
<field name="amount">0.08</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sal_vat8"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_vat8"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sal_vat8"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_vat8"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_in_vat10" model="account.tax.template">
|
||||
<field name="name">Input VAT 10%</field>
|
||||
<field name="description">Input VAT 10%</field>
|
||||
<field name="amount">0.10</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="a189200"/>
|
||||
<field name="account_paid_id" ref="a189200"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_vat10"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_vat10"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_vat10"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_vat10"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_tax_12" model="account.tax.template">
|
||||
<field name="name">VAT-12.5%</field>
|
||||
<field name="price_include" eval="0"/>
|
||||
<field name="amount">12.5</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<!-- Exice Duty -->
|
||||
|
||||
<record id="exice_duty_private_main" model="account.tax.template">
|
||||
<field name="name">Excise Duty-10.30%</field>
|
||||
<field name="include_base_amount" eval="True"/>
|
||||
<record id="vat_private_out_vat10" model="account.tax.template">
|
||||
<field name="name">Output VAT 10%</field>
|
||||
<field name="description">Output VAT 10%</field>
|
||||
<field name="amount">0.10</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="a2164"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="base_sign">1</field>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="tax_sign">1</field>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_base_sign">1</field>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_tax_sign">1</field>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sal_vat10"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_vat10"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sal_vat10"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_vat10"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="exice_private_duty_parent" model="account.tax.template">
|
||||
<field name="name">Excise Duty-2%</field>
|
||||
<field name="amount">0.02</field>
|
||||
|
||||
<record id="vat_private_in_vat12" model="account.tax.template">
|
||||
<field name="name">Input VAT 12.5%</field>
|
||||
<field name="description">Input VAT 12.5%</field>
|
||||
<field name="amount">0.125</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="a189200"/>
|
||||
<field name="account_paid_id" ref="a189200"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_vat12"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_vat12"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_vat12"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_vat12"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="vat_private_out_vat12" model="account.tax.template">
|
||||
<field name="name">Output VAT 12.5%</field>
|
||||
<field name="description">Output VAT 12.5%</field>
|
||||
<field name="amount">0.125</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="parent_id" ref="exice_duty_private_main"/>
|
||||
<field name="account_collected_id" ref="a2164"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="base_sign">1</field>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="tax_sign">1</field>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_base_sign">1</field>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_tax_sign">1</field>
|
||||
<field name="account_collected_id" ref="a2162"/>
|
||||
<field name="account_paid_id" ref="a2162"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sal_vat12"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_vat12"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sal_vat12"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_vat12"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="exice_private_duty" model="account.tax.template">
|
||||
<field name="name">Excise Duty-1%</field>
|
||||
<field name="amount">0.01</field>
|
||||
<field name="type">percent</field>
|
||||
|
||||
<!-- Exice Duty -->
|
||||
|
||||
<record id="exice_duty_private_sale12" model="account.tax.template">
|
||||
<field name="name">Excise Duty 12% - Sales</field>
|
||||
<field name="description">Excise Duty 12% - Sales</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.1200</field>
|
||||
<field name="account_collected_id" ref="a2164"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="base_sign">1</field>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="tax_sign">1</field>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_base_sign">1</field>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_tax_sign">1</field>
|
||||
<field name="parent_id" ref="exice_duty_private_main"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_exice12"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_exice12"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="exice_duty_private_sale2" model="account.tax.template">
|
||||
<field name="name">Excise Duty 2% - Sales</field>
|
||||
<field name="description">Excise Duty 2% - Sales</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.020</field>
|
||||
<field name="account_collected_id" ref="a2164"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_exice2"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_exice2"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="exice_duty_private_sale1" model="account.tax.template">
|
||||
<field name="name">Output Excise Duty 1%</field>
|
||||
<field name="description">Output Excise Duty 1%</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.0100</field>
|
||||
<field name="account_collected_id" ref="a2164"/>
|
||||
<field name="account_paid_id" ref="a2164"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_exice1"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sales_excise"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_exice1"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<!-- Service Tax -->
|
||||
|
||||
<record id="service_private_main" model="account.tax.template">
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="name">Service Tax-12.30%</field>
|
||||
<field name="include_base_amount" eval="True"/>
|
||||
|
||||
<record id="service_private_ser12_sale" model="account.tax.template">
|
||||
<field name="name">Output Service Tax 12%</field>
|
||||
<field name="description">Output Service Tax 12%</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.12</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="account_collected_id" ref="a2163"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="child_depend" eval="0"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_sale_ser12"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_st12"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_sale_ser12"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_st12"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="service_private_tax_parent" model="account.tax.template">
|
||||
<field name="name">Service Tax-%2</field>
|
||||
|
||||
<record id="service_private_ser2_sale" model="account.tax.template">
|
||||
<field name="name">Output Sales Service Tax 2%</field>
|
||||
<field name="description">Output Sales Service Tax 2%</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.02</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="sequence">3</field>
|
||||
<field name="account_collected_id" ref="a2163"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="parent_id" ref="service_private_main"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_st2"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_st2"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="parent_id" ref="service_private_ser12_sale"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="service_private_tax" model="account.tax.template">
|
||||
<field name="name">Service Tax-%1</field>
|
||||
|
||||
<record id="service_private_ser1_sale" model="account.tax.template">
|
||||
<field name="name">Output Service Tax 1%</field>
|
||||
<field name="description">Output Service Tax 1%</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.01</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="type_tax_use">all</field>
|
||||
<field name="sequence">5</field>
|
||||
<field name="account_collected_id" ref="a2163"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_base_tax_sale"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec"/>
|
||||
<field name="parent_id" ref="service_private_main"/>
|
||||
<field name="account_paid_id" ref="a2163"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_rec_st1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_rec_st1"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="parent_id" ref="service_private_ser12_sale"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="service_private_ser12_purchase" model="account.tax.template">
|
||||
<field name="name">Input Service Tax 12%</field>
|
||||
<field name="description">Input Service Tax 12%</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.1200</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="account_collected_id" ref="a189300"/>
|
||||
<field name="account_paid_id" ref="a189300"/>
|
||||
<field name="base_code_id" ref="vat_code_tax_pur_ser12"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_ic_st"/>
|
||||
<field name="ref_base_code_id" ref="vat_code_tax_pur_ser12"/>
|
||||
<field name="ref_base_sign" eval="-1"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_ic_st"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="service_private_ser2_purchase" model="account.tax.template">
|
||||
<field name="name">Input Service Tax Edu. Cess. 2%</field>
|
||||
<field name="description">Input Service Tax Edu. Cess. 2%</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.0200</field>
|
||||
<field name="sequence">3</field>
|
||||
<field name="account_collected_id" ref="a189300"/>
|
||||
<field name="account_paid_id" ref="a189300"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_ic_edu_cess"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pur_PCST5"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="parent_id" ref="service_private_ser12_purchase"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
<record id="service_private_ser1_purchase" model="account.tax.template">
|
||||
<field name="name">Input Service Tax Seco. & HEC 1%</field>
|
||||
<field name="description">Input Service Tax Seco. & HEC 1%</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type">percent</field>
|
||||
<field name="amount">0.0100</field>
|
||||
<field name="sequence">5</field>
|
||||
<field name="account_collected_id" ref="a189300"/>
|
||||
<field name="account_paid_id" ref="a189300"/>
|
||||
<field name="tax_code_id" ref="vat_code_tax_pay_ic_seco_hec"/>
|
||||
<field name="ref_tax_code_id" ref="vat_code_tax_pay_ic_seco_hec"/>
|
||||
<field name="ref_tax_sign" eval="-1"/>
|
||||
<field name="parent_id" ref="service_private_ser12_purchase"/>
|
||||
<field name="chart_template_id" ref="indian_chart_template_private"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -116,7 +116,7 @@
|
|||
<record model="account.account.template" id="p15400">
|
||||
<field name="name">Tax Receivable</field>
|
||||
<field name="code">15400</field>
|
||||
<field name="type">other</field>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="account.data_account_type_asset"/>
|
||||
<field name="reconcile" eval="False"/>
|
||||
<field name="parent_id" ref="p10000"/>
|
||||
|
@ -658,7 +658,327 @@
|
|||
<field name="reconcile" eval="False"/>
|
||||
<field name="parent_id" ref="p96000"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="account.account.template" id="p154001">
|
||||
<field name="name">Input CST 5%</field>
|
||||
<field name="code">154001</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_expense"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154002">
|
||||
<field name="name">Input Service Tax Seco. & HEC 1%</field>
|
||||
<field name="code">154002</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154003">
|
||||
<field name="name">Input Credit - URD</field>
|
||||
<field name="code">154003</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154004">
|
||||
<field name="name">TDS on Audit Fees - 94J</field>
|
||||
<field name="code">154004</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154005">
|
||||
<field name="name">TDS on Commission Or Brokerage - 94H</field>
|
||||
<field name="code">154005</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154006">
|
||||
<field name="name">Input Credit - Import Duty</field>
|
||||
<field name="code">154006</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154007">
|
||||
<field name="name">Additional Duty (Imports) 4%</field>
|
||||
<field name="code">154007</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154008">
|
||||
<field name="name">Input Service Tax 12%</field>
|
||||
<field name="code">154008</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154009">
|
||||
<field name="name">Input Service Tax Edu. Cess. 2%</field>
|
||||
<field name="code">154009</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154010">
|
||||
<field name="name">TDS on Salary - 92B</field>
|
||||
<field name="code">154010</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154011">
|
||||
<field name="name">Input Excise Duty 6%</field>
|
||||
<field name="code">154011</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154012">
|
||||
<field name="name">Input Excise Duty 5%</field>
|
||||
<field name="code">154012</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154013">
|
||||
<field name="name">Input Excise Duty 12%</field>
|
||||
<field name="code">154013</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154014">
|
||||
<field name="name">Education Cess 2% - Purchase</field>
|
||||
<field name="code">154014</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154015">
|
||||
<field name="name">Seco. & Higher Edu. Cess 1% - Purchase</field>
|
||||
<field name="code">154015</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247001">
|
||||
<field name="name">Excise Duty 12% - Sales</field>
|
||||
<field name="code">247001</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247010">
|
||||
<field name="name">Education Cess 2% - Sales</field>
|
||||
<field name="code">247010</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247002">
|
||||
<field name="name">Seco. & Higher Edu. Cess 1% - Sales</field>
|
||||
<field name="code">247002</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154016">
|
||||
<field name="name">Input Sec. & HEC - Capital Goods</field>
|
||||
<field name="code">154016</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154017">
|
||||
<field name="name">TDS on Contractor - 94C</field>
|
||||
<field name="code">154017</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154018">
|
||||
<field name="name">TDS on Director's Interest</field>
|
||||
<field name="code">154018</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154019">
|
||||
<field name="name">TDS on Director's Remuneration - 92B</field>
|
||||
<field name="code">154019</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154020">
|
||||
<field name="name">TDS on Interest</field>
|
||||
<field name="code">154020</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154021">
|
||||
<field name="name">TDS on Professional Fees - 94J</field>
|
||||
<field name="code">154021</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154022">
|
||||
<field name="name">TDS on Rent - 94I</field>
|
||||
<field name="code">154022</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154023">
|
||||
<field name="name">Input Edu. Cess - Capital Goods</field>
|
||||
<field name="code">154023</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154024">
|
||||
<field name="name">Input Excise Duty 12% - Capital Goods</field>
|
||||
<field name="code">154024</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154025">
|
||||
<field name="name">Input VAT 4%</field>
|
||||
<field name="code">154025</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154026">
|
||||
<field name="name">Input Additional VAT 1%</field>
|
||||
<field name="code">154026</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154027">
|
||||
<field name="name">Input VAT 15%</field>
|
||||
<field name="code">154027</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247003">
|
||||
<field name="name">Output VAT 4%</field>
|
||||
<field name="code">247003</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247004">
|
||||
<field name="name">Output Adi. VAT 1%</field>
|
||||
<field name="code">247004</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247005">
|
||||
<field name="name">CST 2% on Sales - Against Form - C</field>
|
||||
<field name="code">247005</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247006">
|
||||
<field name="name">CST 5% on Sales</field>
|
||||
<field name="code">247006</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154028">
|
||||
<field name="name">Input VAT 12.5%</field>
|
||||
<field name="code">154028</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154029">
|
||||
<field name="name">Input Additional VAT 2.5%</field>
|
||||
<field name="code">154029</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p154030">
|
||||
<field name="name">Input CST 2%</field>
|
||||
<field name="code">154030</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_expense"/>
|
||||
<field name="parent_id" ref="p15400"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247007">
|
||||
<field name="name">CST 2% on Sales - CT3 Against Form C</field>
|
||||
<field name="code">247007</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247008">
|
||||
<field name="name">Output VAT 4% on Sales - CT3</field>
|
||||
<field name="code">247008</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account.template" id="p247009">
|
||||
<field name="name">Output Adi. VAT 1% Sales CT3</field>
|
||||
<field name="code">247009</field>
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="account.data_account_type_liability"/>
|
||||
<field name="parent_id" ref="p24700"/>
|
||||
</record>
|
||||
|
||||
<record id="indian_chart_template_public" model="account.chart.template">
|
||||
<field name="name">India - Chart of Accounts for Public Ltd</field>
|
||||
<field name="account_root_id" ref="p0"/>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,7 @@
|
|||
|
||||
<record model="account.tax.code.template" id="vat_code_payable">
|
||||
<field name="name">Tax Paid</field>
|
||||
<field name="sign">-1</field>
|
||||
<field name="parent_id" ref="vat_code_balance_net"/>
|
||||
</record>
|
||||
|
||||
|
@ -27,16 +28,540 @@
|
|||
<field name="parent_id" ref="vat_code_tax"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_sale">
|
||||
<field name="name">Base of Taxed Sales</field>
|
||||
<field name="name">Taxable Sale Bases</field>
|
||||
<field name="parent_id" ref="vat_code_base_net"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_purchase">
|
||||
<field name="name">Base of Taxed Purchases</field>
|
||||
<field name="name">Taxable Purchase Bases</field>
|
||||
<field name="parent_id" ref="vat_code_base_net"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_CSTP5">
|
||||
<field name="name">Input CST 5%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_PCST5">
|
||||
<field name="name">Purchase CST 5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_ser12">
|
||||
<field name="name">Purchase Service Tax 12%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sale_ser12">
|
||||
<field name="name">Sales Service Tax 12%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_exice_salebase">
|
||||
<field name="name">Excise Duty 12.36% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_exice12">
|
||||
<field name="name">Excise Duty 12% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_exice_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_exice2">
|
||||
<field name="name">Excise Duty 2% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_exice1">
|
||||
<field name="name">Excise Duty 1% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_ic_st_purbase">
|
||||
<field name="name">Excise Duty 12.36% - Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_exice12">
|
||||
<field name="name">Excise Duty 12% - Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_purbase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_cess2">
|
||||
<field name="name">Education Cess 2% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_exice_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_cess2">
|
||||
<field name="name">Education Cess 2% - Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_purbase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_import_duty">
|
||||
<field name="name">Input Credit - Import Duty</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_edu_cess">
|
||||
<field name="name">Input Credit On Capital Goods - Edu. Cess</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_cap_goods">
|
||||
<field name="name">Input Excise Duty 12% - Capital Goods</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_seco_hec">
|
||||
<field name="name">Input Credit on Capital Goods - Seco. & HEC</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_ic_st_base">
|
||||
<field name="name">Input Service Tax 12.36%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_ic_st">
|
||||
<field name="name">Input Service Tax 12%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_base"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_ic_edu_cess">
|
||||
<field name="name">Input Service Tax Edu. Cess. 2%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_base"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_ic_seco_hec">
|
||||
<field name="name">Input Service Tax Seco. & HEC 1%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_base"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_sec_hig_edu">
|
||||
<field name="name">Seco. & Higher Edu. Cess 1% - Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_tax_pay_ic_st_purbase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_sec_hig_cess">
|
||||
<field name="name">Seco. & Higher Edu. Cess 1% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_exice_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_cst2">
|
||||
<field name="name">CST 2% on Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_cst5">
|
||||
<field name="name">CST 5% on Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_add_vat1">
|
||||
<field name="name">Input Additional VAT 1%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_add_vat2">
|
||||
<field name="name">Input Additional Vat 2.5%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat12">
|
||||
<field name="name">Input VAT 12.5%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat15">
|
||||
<field name="name">Input VAT 15%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat10">
|
||||
<field name="name">Input VAT 10%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat8">
|
||||
<field name="name">Input VAT 8%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat5">
|
||||
<field name="name">Input VAT 5%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_vat4">
|
||||
<field name="name">Input VAT 4%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat15">
|
||||
<field name="name">Output VAT 15%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat12">
|
||||
<field name="name">Output VAT 12.5%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat10">
|
||||
<field name="name">Output VAT 10%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat8">
|
||||
<field name="name">Output VAT 8%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat5">
|
||||
<field name="name">Output VAT 5%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_vat4">
|
||||
<field name="name">Output VAT 4%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_add_vat1">
|
||||
<field name="name">Output Adi. VAT 1%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_cst2">
|
||||
<field name="name">CST 2% on Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_exice5">
|
||||
<field name="name">Input Excise Duty 5%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_exice6">
|
||||
<field name="name">Input Excise Duty 6%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_urd">
|
||||
<field name="name">Input Credit - URD</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_audit_fee">
|
||||
<field name="name">TDS on Audit Fees - 94J</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_brokerage">
|
||||
<field name="name">TDS on Commission Or Brokerage- 94H</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_contractor">
|
||||
<field name="name">TDS on Contractor-94C</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_dir_intrest">
|
||||
<field name="name">TDS on Director's Interest</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_dir_ren">
|
||||
<field name="name">TDS on Director's Remuneration - 92B</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_intrest">
|
||||
<field name="name">TDS on Interest</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_prof_fee">
|
||||
<field name="name">TDS on Professional Fees - 94J</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_rent">
|
||||
<field name="name">TDS on Rent - 94I</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_tds_sal">
|
||||
<field name="name">TDS on Salary - 92B</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_tds_pur_import">
|
||||
<field name="name">Import Purchase</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat">
|
||||
<field name="name">Purchase VAT 4% / VAT 12.5% / VAT 15% / CST 2% / CST 5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_plant_machinery">
|
||||
<field name="name">Plant & Machinery</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_exp_act">
|
||||
<field name="name">Expense Accounts</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sales_excise">
|
||||
<field name="name">Sales Excise</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sale_cst2">
|
||||
<field name="name">Sales CST 2%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sale_cst15">
|
||||
<field name="name">Sales CST 5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat15">
|
||||
<field name="name">Purchase VAT 15%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat12">
|
||||
<field name="name">Purchase VAT 12.5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat10">
|
||||
<field name="name">Purchase VAT 10%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat8">
|
||||
<field name="name">Purchase VAT 8%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat5">
|
||||
<field name="name">Purchase VAT 5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat4">
|
||||
<field name="name">Purchase VAT 4%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_vat25">
|
||||
<field name="name">Purchase VAT 2.5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat15">
|
||||
<field name="name">Sales VAT 15%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat12">
|
||||
<field name="name">Sales VAT 12.5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat10">
|
||||
<field name="name">Sales VAT 10%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat8">
|
||||
<field name="name">Sales VAT 8%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat5">
|
||||
<field name="name">Sales VAT 5%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_vat4">
|
||||
<field name="name">Sales VAT 4%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_cst2">
|
||||
<field name="name">Input CST 2%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_urd">
|
||||
<field name="name">Purchase URD</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pur_base_tds">
|
||||
<field name="name">Base Expenses for TDS</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_pay_add_imp_duty">
|
||||
<field name="name">Additional Duty (Imports) 4%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_formh_tax">
|
||||
<field name="name">Sales Export - Form H - With Tax</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_cst2_on_sal_cst3">
|
||||
<field name="name">CST 2% on Sales CT3</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_cst3">
|
||||
<field name="name">Sales CT3 VAT</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_out4_sal_cst3">
|
||||
<field name="name">Output VAT 4% on Sales CT3</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_out_add1_sale_cst3">
|
||||
<field name="name">Output Adi. VAT 1% on Sales CT3</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_ct3_cst">
|
||||
<field name="name">Sales CT3 CST</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_exp_ct1">
|
||||
<field name="name">Sales Export - Form H - With CT1</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_sez_out_guj">
|
||||
<field name="name">Sales Export - SEZ - Out of Gujarat</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_sez_in_guj">
|
||||
<field name="name">Sales Export - SEZ - In Gujarat</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_no_saz_ogs">
|
||||
<field name="name">No Tax SEZ OGS</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_no_sez_guj">
|
||||
<field name="name">No Tax SEZ Gujarat</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_out_country">
|
||||
<field name="name">Sales Export - Out of Country</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_sal_proj">
|
||||
<field name="name">Sales Others (Projects)</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_formh_bed">
|
||||
<field name="name">No Tax Form H with BED</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_fomh">
|
||||
<field name="name">No Tax Form H</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_no_out_country">
|
||||
<field name="name">No Tax Export Out of Country</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_no_proj">
|
||||
<field name="name">No Tax Projects</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_st_salebase">
|
||||
<field name="name">Service Tax 12.36% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_st12">
|
||||
<field name="name">Service Tax 12% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_st_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_st2">
|
||||
<field name="name">Service Tax 2% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_st_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_tax_rec_st1">
|
||||
<field name="name">Service Tax 1% - Sales</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec_st_salebase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_sale15">
|
||||
<field name="name">Sales Tax 15%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_rec_sale15">
|
||||
<field name="name">Sales Tax - 15%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_sale12">
|
||||
<field name="name">Sales Tax 12%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_rec_sale12">
|
||||
<field name="name">Sales Tax - 12%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_sale4">
|
||||
<field name="name">Sales Tax 4%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_sale"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_rec_sale4">
|
||||
<field name="name">Sales Tax - 4%</field>
|
||||
<field name="parent_id" ref="vat_code_tax_rec"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_base_tax_pur15">
|
||||
<field name="name">Purchase Tax 15%</field>
|
||||
<field name="parent_id" ref="vat_code_base_tax_purchase"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.code.template" id="vat_code_pay_pur4">
|
||||
<field name="name">Purchase Tax - 15%</field>
|
||||
<field name="parent_id" ref="vat_code_payable"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
# Chinese (Simplified) translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:06+0000\n"
|
||||
"PO-Revision-Date: 2013-07-24 12:29+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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: 2013-07-25 05:13+0000\n"
|
||||
"X-Generator: Launchpad (build 16700)\n"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position_template
|
||||
msgid "Template for Fiscal Position"
|
||||
msgstr "财务结构模板"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.account:0
|
||||
msgid "The code of the account must be unique per company !"
|
||||
msgstr "该科目的代码,每家公司必须是唯一的!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account.template:0
|
||||
msgid ""
|
||||
"Configuration Error!\n"
|
||||
"You can not define children to an account with internal type different of "
|
||||
"\"View\"! "
|
||||
msgstr ""
|
||||
"配置错误! \n"
|
||||
"上级科目必须是“视图”类型的科目! "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_analytic_journal
|
||||
msgid "Analytic Journal"
|
||||
msgstr "辅助核算类型"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account.template:0
|
||||
msgid "Error ! You can not create recursive account templates."
|
||||
msgstr "错误!您不能创建递归的科目模板。"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_journal
|
||||
msgid "Journal"
|
||||
msgstr "分录序时薄"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_chart_template
|
||||
msgid "Templates for Account Chart"
|
||||
msgstr "科目一览表模板"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.tax:0
|
||||
msgid "The description must be unique per company!"
|
||||
msgstr "此说明必须是每个公司唯一的"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.tax.code.template:0
|
||||
msgid "Error ! You can not create recursive Tax Codes."
|
||||
msgstr "错误!您不能创建递归的税编码。"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax_template
|
||||
msgid "account.tax.template"
|
||||
msgstr "account.tax.template"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax
|
||||
msgid "account.tax"
|
||||
msgstr "account.tax"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_account
|
||||
msgid "Account"
|
||||
msgstr "科目"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_wizard_multi_charts_accounts
|
||||
msgid "wizard.multi.charts.accounts"
|
||||
msgstr "wizard.multi.charts.accounts"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.journal:0
|
||||
msgid ""
|
||||
"Configuration error! The currency chosen should be shared by the default "
|
||||
"accounts too."
|
||||
msgstr "设置错误!所选币种应与默认科目共享。"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_account_template
|
||||
msgid "Templates for Accounts"
|
||||
msgstr "科目模板"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: help:account.chart.template,spoken_languages:0
|
||||
msgid ""
|
||||
"State here the languages for which the translations of templates could be "
|
||||
"loaded at the time of installation of this localization module and copied in "
|
||||
"the final object when generating them from templates. You must provide the "
|
||||
"language codes separated by ';'"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid "Error ! You can not create recursive accounts."
|
||||
msgstr "错误!您不能创建递归的科目"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid ""
|
||||
"Configuration Error! \n"
|
||||
"You can not select an account type with a deferral method different of "
|
||||
"\"Unreconciled\" for accounts with internal type \"Payable/Receivable\"! "
|
||||
msgstr ""
|
||||
"配置错误!\n"
|
||||
"对于内部类型是‘应收/应付’的会计科目,你需要选择结转方式是‘未核销’的科目类型。 "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The name of the journal must be unique per company !"
|
||||
msgstr "每个公司的日记账名称必须唯一!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_analytic_account
|
||||
msgid "Analytic Account"
|
||||
msgstr "辅助核算项目"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The code of the journal must be unique per company !"
|
||||
msgstr "每个公司的日记账代码必须唯一!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position
|
||||
msgid "Fiscal Position"
|
||||
msgstr "财务结构"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid ""
|
||||
"Configuration Error! \n"
|
||||
"You can not define children to an account with internal type different of "
|
||||
"\"View\"! "
|
||||
msgstr ""
|
||||
"配置错误! \n"
|
||||
"您不能给 非“视图”类型的科目定义一个子科目。 "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.analytic.account:0
|
||||
msgid "Error! You can not create recursive analytic accounts."
|
||||
msgstr "错误! 你不能创建递归的辅助核算项目"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax_code_template
|
||||
msgid "Tax Code Template"
|
||||
msgstr "税编码模板"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: field:account.chart.template,spoken_languages:0
|
||||
msgid "Spoken Languages"
|
||||
msgstr "交流语言"
|
|
@ -0,0 +1,17 @@
|
|||
.. _changelog:
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
`trunk (saas-2)`
|
||||
----------------
|
||||
|
||||
- added support of ``active_domain`` form context, coming from the list view.
|
||||
When checking the header hook, the mass mailing will be done on all records
|
||||
matching the ``active_domain``.
|
||||
- added ``mail_server_id`` to mail_message, removing it from mail_mail. This allows
|
||||
to set the preferred mail server to use for notifications emails, when using
|
||||
templates.
|
||||
- added ``_mail_post_access`` attribute that specifies the access right that
|
||||
should have the user in order to post a new message on a given model. Values
|
||||
are ``read`` (portal documents), ``write`` (default value), ``unlink`` or ``create``.
|
|
@ -12,3 +12,12 @@ Mail Module documentation topics
|
|||
mail_partner
|
||||
mail_state
|
||||
mail_subtype
|
||||
|
||||
|
||||
Changelog
|
||||
'''''''''
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
changelog.rst
|
||||
|
|
|
@ -151,7 +151,7 @@ class mail_notification(osv.Model):
|
|||
return footer
|
||||
|
||||
def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None,
|
||||
force_send=False, user_signature=True):
|
||||
force_send=False, user_signature=True):
|
||||
""" Send by email the notification depending on the user preferences
|
||||
|
||||
:param list partners_to_notify: optional list of partner ids restricting
|
||||
|
|
|
@ -44,7 +44,6 @@ class mail_mail(osv.Model):
|
|||
|
||||
_columns = {
|
||||
'mail_message_id': fields.many2one('mail.message', 'Message', required=True, ondelete='cascade'),
|
||||
'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
|
||||
'state': fields.selection([
|
||||
('outgoing', 'Outgoing'),
|
||||
('sent', 'Sent'),
|
||||
|
|
|
@ -191,6 +191,7 @@ class mail_message(osv.Model):
|
|||
'vote_user_ids': fields.many2many('res.users', 'mail_vote',
|
||||
'message_id', 'user_id', string='Votes',
|
||||
help='Users that voted for this message'),
|
||||
'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
|
||||
}
|
||||
|
||||
def _needaction_domain_get(self, cr, uid, context=None):
|
||||
|
@ -780,8 +781,8 @@ class mail_message(osv.Model):
|
|||
values['message_id'] = tools.generate_tracking_message_id('private')
|
||||
newid = super(mail_message, self).create(cr, uid, values, context)
|
||||
self._notify(cr, uid, newid, context=context,
|
||||
force_send=context.get('mail_notify_force_send', True),
|
||||
user_signature=context.get('mail_notify_user_signature', True))
|
||||
force_send=context.get('mail_notify_force_send', True),
|
||||
user_signature=context.get('mail_notify_user_signature', True))
|
||||
# TDE FIXME: handle default_starred. Why not setting an inv on starred ?
|
||||
# Because starred will call set_message_starred, that looks for notifications.
|
||||
# When creating a new mail_message, it will create a notification to a message
|
||||
|
|
|
@ -70,6 +70,7 @@ class mail_thread(osv.AbstractModel):
|
|||
_name = 'mail.thread'
|
||||
_description = 'Email Thread'
|
||||
_mail_flat_thread = True
|
||||
_mail_post_access = 'write'
|
||||
|
||||
# Automatic logging system if mail installed
|
||||
# _track = {
|
||||
|
@ -156,12 +157,26 @@ class mail_thread(osv.AbstractModel):
|
|||
res[id]['message_summary'] = "<span class='oe_kanban_mail_new' title='%s'><span class='oe_e'>9</span> %d %s</span>" % (title, res[id].pop('message_unread_count'), _("New"))
|
||||
return res
|
||||
|
||||
def _get_subscription_data(self, cr, uid, ids, name, args, context=None):
|
||||
def read_followers_data(self, cr, uid, follower_ids, context=None):
|
||||
result = []
|
||||
technical_group = self.pool.get('ir.model.data').get_object(cr, uid, 'base', 'group_no_one')
|
||||
for follower in self.pool.get('res.partner').browse(cr, uid, follower_ids, context=context):
|
||||
is_editable = uid in map(lambda x: x.id, technical_group.users)
|
||||
is_uid = uid in map(lambda x: x.id, follower.user_ids)
|
||||
data = (follower.id,
|
||||
follower.name,
|
||||
{'is_editable': is_editable, 'is_uid': is_uid},
|
||||
)
|
||||
result.append(data)
|
||||
return result
|
||||
|
||||
def _get_subscription_data(self, cr, uid, ids, name, args, user_pid=None, context=None):
|
||||
""" Computes:
|
||||
- message_subtype_data: data about document subtypes: which are
|
||||
available, which are followed if any """
|
||||
res = dict((id, dict(message_subtype_data='')) for id in ids)
|
||||
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
|
||||
if user_pid is None:
|
||||
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
|
||||
|
||||
# find current model subtypes, add them to a dictionary
|
||||
subtype_obj = self.pool.get('mail.message.subtype')
|
||||
|
@ -495,12 +510,22 @@ class mail_thread(osv.AbstractModel):
|
|||
access rule on the document, for portal document such as issues. """
|
||||
if not model_obj:
|
||||
model_obj = self
|
||||
if operation in ['create', 'write', 'unlink']:
|
||||
model_obj.check_access_rights(cr, uid, 'write')
|
||||
model_obj.check_access_rule(cr, uid, mids, 'write', context=context)
|
||||
if hasattr(self, '_mail_post_access'):
|
||||
create_allow = self._mail_post_access
|
||||
else:
|
||||
model_obj.check_access_rights(cr, uid, operation)
|
||||
model_obj.check_access_rule(cr, uid, mids, operation, context=context)
|
||||
create_allow = 'write'
|
||||
|
||||
if operation in ['write', 'unlink']:
|
||||
check_operation = 'write'
|
||||
elif operation == 'create' and create_allow in ['create', 'read', 'write', 'unlink']:
|
||||
check_operation = create_allow
|
||||
elif operation == 'create':
|
||||
check_operation = 'write'
|
||||
else:
|
||||
check_operation = operation
|
||||
|
||||
model_obj.check_access_rights(cr, uid, check_operation)
|
||||
model_obj.check_access_rule(cr, uid, mids, check_operation, context=context)
|
||||
|
||||
def _get_formview_action(self, cr, uid, id, model=None, context=None):
|
||||
""" Return an action to open the document. This method is meant to be
|
||||
|
@ -1401,9 +1426,9 @@ class mail_thread(osv.AbstractModel):
|
|||
# Followers API
|
||||
#------------------------------------------------------
|
||||
|
||||
def message_get_subscription_data(self, cr, uid, ids, context=None):
|
||||
def message_get_subscription_data(self, cr, uid, ids, user_pid=None, context=None):
|
||||
""" Wrapper to get subtypes data. """
|
||||
return self._get_subscription_data(cr, uid, ids, None, None, context=context)
|
||||
return self._get_subscription_data(cr, uid, ids, None, None, user_pid=user_pid, context=context)
|
||||
|
||||
def message_subscribe_users(self, cr, uid, ids, user_ids=None, subtype_ids=None, context=None):
|
||||
""" Wrapper on message_subscribe, using users. If user_ids is not
|
||||
|
|
|
@ -14,11 +14,22 @@
|
|||
<record id="mail_followers_read_write_own" model="ir.rule">
|
||||
<field name="name">mail.followers: read and write its own entries</field>
|
||||
<field name="model_id" ref="model_mail_followers"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<!-- If technical rights then read and write others subscriptions -->
|
||||
<record id="mail_followers_read_write_others" model="ir.rule">
|
||||
<field name="name">mail.followers: read and write others entries</field>
|
||||
<field name="model_id" ref="model_mail_followers"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_no_one'))]"/>
|
||||
<field name="domain_force">[]</field>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="mail_notification_read_write_own" model="ir.rule">
|
||||
<field name="name">mail.notification: read and write its own entries</field>
|
||||
<field name="model_id" ref="model_mail_notification"/>
|
||||
|
|
|
@ -21,7 +21,7 @@ email overload.
|
|||
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=mail" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -632,11 +632,10 @@
|
|||
}
|
||||
.openerp .oe_followers .oe_partner {
|
||||
height: 32px;
|
||||
margin-right: 8px;
|
||||
margin-right: 24px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.openerp .oe_followers .oe_partner img{
|
||||
width: 32px;
|
||||
|
@ -649,7 +648,18 @@
|
|||
right: 0px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.openerp .oe_followers .oe_edit_subtype{
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.openerp .oe_followers .oe_partner .oe_hidden{
|
||||
display: none;
|
||||
}
|
||||
.openerp.ui-dialog .ui-dialog-titlebar .ui-dialog-title{
|
||||
padding-right: 20px;
|
||||
}
|
||||
.openerp .oe_followers .oe_show_more{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ openerp.mail = function (session) {
|
|||
var _t = session.web._t,
|
||||
_lt = session.web._lt;
|
||||
|
||||
var mail = session.mail = {};
|
||||
var mail = session.mail;
|
||||
|
||||
openerp_mail_followers(session, mail); // import mail_followers.js
|
||||
openerp_FieldMany2ManyTagsEmail(session); // import manyy2many_tags_email.js
|
||||
|
@ -966,6 +966,24 @@ openerp.mail = function (session) {
|
|||
this.$('.oe_reply').on('click', this.on_message_reply);
|
||||
this.$('.oe_star').on('click', this.on_star);
|
||||
this.$('.oe_msg_vote').on('click', this.on_vote);
|
||||
this.$('.oe_mail_action_model').on('click', this.on_record_clicked);
|
||||
},
|
||||
|
||||
on_record_clicked: function (event) {
|
||||
event.stopPropagation();
|
||||
var state = {
|
||||
'model': this.model,
|
||||
'id': this.res_id,
|
||||
'title': this.record_name
|
||||
};
|
||||
session.webclient.action_manager.do_push_state(state);
|
||||
this.do_action({
|
||||
res_model: state.model,
|
||||
res_id: state.id,
|
||||
type: 'ir.actions.act_window',
|
||||
views: [[false, 'form']]
|
||||
});
|
||||
return false;
|
||||
},
|
||||
|
||||
/* Call the on_compose_message on the thread of this message. */
|
||||
|
|
|
@ -29,7 +29,6 @@ openerp_mail_followers = function(session, mail) {
|
|||
this.displayed_limit = this.node.attrs.displayed_nb || 10;
|
||||
this.displayed_nb = this.displayed_limit;
|
||||
this.ds_model = new session.web.DataSetSearch(this, this.view.model);
|
||||
this.ds_follow = new session.web.DataSetSearch(this, this.field.relation);
|
||||
this.ds_users = new session.web.DataSetSearch(this, 'res.users');
|
||||
|
||||
this.value = [];
|
||||
|
@ -74,10 +73,33 @@ openerp_mail_followers = function(session, mail) {
|
|||
this.$el.on('click', '.oe_subtype_list input', self.do_update_subscription);
|
||||
// event: click on 'invite' button, that opens the invite wizard
|
||||
this.$('.oe_invite').on('click', self.on_invite_follower);
|
||||
// event: click on 'edit_subtype(pencil)' button to edit subscription
|
||||
this.$el.on('click', '.oe_edit_subtype', self.on_edit_subtype);
|
||||
this.$el.on('click', '.oe_remove_follower', self.on_remove_follower);
|
||||
this.$el.on('click', '.oe_show_more', self.on_show_more_followers)
|
||||
},
|
||||
|
||||
on_edit_subtype: function(event) {
|
||||
var self = this;
|
||||
var $currentTarget = $(event.currentTarget);
|
||||
var user_pid = $currentTarget.data('id');
|
||||
$('div.oe_edit_actions').remove();
|
||||
self.$dialog = new session.web.dialog($('<div class="oe_edit_actions">'), {
|
||||
modal: true,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
title: _t('Edit Subscription of ') + $currentTarget.siblings('a').text(),
|
||||
buttons: [
|
||||
{ text: _t("Apply"), click: function() {
|
||||
self.do_update_subscription(event, user_pid);
|
||||
$(this).dialog("close");
|
||||
}},
|
||||
{ text: _t("Cancel"), click: function() { $(this).dialog("close"); }}
|
||||
],
|
||||
});
|
||||
return self.fetch_subtypes(user_pid);
|
||||
},
|
||||
|
||||
on_invite_follower: function (event) {
|
||||
var self = this;
|
||||
var action = {
|
||||
|
@ -130,7 +152,7 @@ openerp_mail_followers = function(session, mail) {
|
|||
|
||||
fetch_followers: function (value_) {
|
||||
this.value = value_ || {};
|
||||
return this.ds_follow.call('read', [this.value, ['name', 'user_ids']])
|
||||
return this.ds_model.call('read_followers_data', [this.value])
|
||||
.then(this.proxy('display_followers'), this.proxy('fetch_generic'))
|
||||
.then(this.proxy('display_buttons'))
|
||||
.then(this.proxy('fetch_subtypes'));
|
||||
|
@ -147,6 +169,7 @@ openerp_mail_followers = function(session, mail) {
|
|||
self.message_is_follower = (_.indexOf(self.value, pid) != -1);
|
||||
}).then(self.proxy('display_generic'));
|
||||
},
|
||||
|
||||
_format_followers: function(count){
|
||||
var str = '';
|
||||
if(count <= 0){
|
||||
|
@ -158,6 +181,7 @@ openerp_mail_followers = function(session, mail) {
|
|||
}
|
||||
return str;
|
||||
},
|
||||
|
||||
/* Display generic info about follower, for people not having access to res_partner */
|
||||
display_generic: function () {
|
||||
var self = this;
|
||||
|
@ -168,16 +192,32 @@ openerp_mail_followers = function(session, mail) {
|
|||
/** Display the followers */
|
||||
display_followers: function (records) {
|
||||
var self = this;
|
||||
this.message_is_follower = false;
|
||||
this.followers = records || this.followers;
|
||||
this.message_is_follower = this.set_is_follower(this.followers);
|
||||
// clean and display title
|
||||
var node_user_list = this.$('.oe_follower_list').empty();
|
||||
this.$('.oe_follower_title').html(this._format_followers(this.followers.length));
|
||||
// truncate number of displayed followers
|
||||
var truncated = this.followers.slice(0, this.displayed_nb);
|
||||
_(truncated).each(function (record) {
|
||||
record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id);
|
||||
$(session.web.qweb.render('mail.followers.partner', {'record': record, 'widget': self})).appendTo(node_user_list);
|
||||
partner = {
|
||||
'id': record[0],
|
||||
'name': record[1],
|
||||
'is_uid': record[2]['is_uid'],
|
||||
'is_editable': record[2]['is_editable'],
|
||||
'avatar_url': mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record[0]),
|
||||
}
|
||||
if (partner.is_uid) {
|
||||
self.message_is_follower = partner.is_uid;
|
||||
}
|
||||
$(session.web.qweb.render('mail.followers.partner', {'record': partner, 'widget': self})).appendTo(node_user_list);
|
||||
// On mouse-enter it will show the edit_subtype pencil.
|
||||
if (partner.is_editable) {
|
||||
self.$('.oe_follower_list').on('mouseenter mouseleave', function(e) {
|
||||
self.$('.oe_edit_subtype').toggleClass('oe_hidden', e.type == 'mouseleave');
|
||||
self.$('.oe_follower_list').find('.oe_partner').toggleClass('oe_partner_name', e.type == 'mouseenter');
|
||||
});
|
||||
}
|
||||
});
|
||||
// FVA note: be sure it is correctly translated
|
||||
if (truncated.length < this.followers.length) {
|
||||
|
@ -185,12 +225,6 @@ openerp_mail_followers = function(session, mail) {
|
|||
}
|
||||
},
|
||||
|
||||
/** Computes whether the current user is in the followers */
|
||||
set_is_follower: function (records) {
|
||||
var user_ids = _.pluck(_.pluck(records, 'user_ids'), 0);
|
||||
return _.indexOf(user_ids, this.session.uid) != -1;
|
||||
},
|
||||
|
||||
display_buttons: function () {
|
||||
if (this.message_is_follower) {
|
||||
this.$('button.oe_follower').removeClass('oe_notfollow').addClass('oe_following');
|
||||
|
@ -206,25 +240,37 @@ openerp_mail_followers = function(session, mail) {
|
|||
},
|
||||
|
||||
/** Fetch subtypes, only if current user is follower */
|
||||
fetch_subtypes: function () {
|
||||
fetch_subtypes: function (user_pid) {
|
||||
var self = this;
|
||||
var subtype_list_ul = this.$('.oe_subtype_list').empty();
|
||||
if (! this.message_is_follower) return;
|
||||
var dialog = false;
|
||||
if (user_pid) {
|
||||
dialog = true;
|
||||
} else {
|
||||
var subtype_list_ul = this.$('.oe_subtype_list').empty();
|
||||
if (! this.message_is_follower) return;
|
||||
}
|
||||
var id = this.view.datarecord.id;
|
||||
this.ds_model.call('message_get_subscription_data', [[id], new session.web.CompoundContext(this.build_context(), {})])
|
||||
.then(function (data) {self.display_subtypes(data, id);});
|
||||
this.ds_model.call('message_get_subscription_data', [[id], user_pid, new session.web.CompoundContext(this.build_context(), {})])
|
||||
.then(function (data) {self.display_subtypes(data, id, dialog);});
|
||||
},
|
||||
|
||||
/** Display subtypes: {'name': default, followed} */
|
||||
display_subtypes:function (data, id) {
|
||||
display_subtypes:function (data, id, dialog) {
|
||||
var self = this;
|
||||
var $list = this.$('.oe_subtype_list');
|
||||
if (dialog) {
|
||||
var $list = self.$dialog;
|
||||
}
|
||||
else {
|
||||
var $list = this.$('.oe_subtype_list');
|
||||
}
|
||||
$list.empty().hide();
|
||||
var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
|
||||
this.records_length = $.map(records, function(value, index) { return index; }).length;
|
||||
if (this.records_length > 1) { self.display_followers(); }
|
||||
_(records).each(function (record, record_name) {
|
||||
record.name = record_name;
|
||||
record.followed = record.followed || undefined;
|
||||
$(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') );
|
||||
$(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo($list);
|
||||
});
|
||||
if (_.size(records) > 1) {
|
||||
$list.show();
|
||||
|
@ -241,35 +287,49 @@ openerp_mail_followers = function(session, mail) {
|
|||
});
|
||||
},
|
||||
|
||||
do_unfollow: function () {
|
||||
do_unfollow: function (user_pid) {
|
||||
if (confirm(_t("Warning! \nYou won't be notified of any email or discussion on this document. Do you really want to unfollow this document ?"))) {
|
||||
_(this.$('.oe_msg_subtype_check')).each(function (record) {
|
||||
$(record).attr('checked',false);
|
||||
});
|
||||
var action_unsubscribe = 'message_unsubscribe_users';
|
||||
var follower_ids = [this.session.uid];
|
||||
if (user_pid) {
|
||||
action_unsubscribe = 'message_unsubscribe';
|
||||
follower_ids = [user_pid];
|
||||
}
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], [this.session.uid], context])
|
||||
.then(this.proxy('read_value'));
|
||||
return this.ds_model.call(action_unsubscribe, [[this.view.datarecord.id], follower_ids, context])
|
||||
.then(this.proxy('read_value'));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
do_update_subscription: function (event) {
|
||||
do_update_subscription: function (event, user_pid) {
|
||||
var self = this;
|
||||
|
||||
var action_subscribe = 'message_subscribe_users';
|
||||
var follower_ids = [this.session.uid];
|
||||
var oe_action = this.$('.oe_actions input[type="checkbox"]');
|
||||
if (user_pid) {
|
||||
action_subscribe = 'message_subscribe';
|
||||
follower_ids = [user_pid];
|
||||
oe_action = $('.oe_edit_actions input[type="checkbox"]');
|
||||
}
|
||||
var checklist = new Array();
|
||||
_(this.$('.oe_actions input[type="checkbox"]')).each(function (record) {
|
||||
_(oe_action).each(function (record) {
|
||||
if ($(record).is(':checked')) {
|
||||
checklist.push(parseInt($(record).data('id')));
|
||||
}
|
||||
});
|
||||
|
||||
if (!checklist.length) {
|
||||
if (!this.do_unfollow()) {
|
||||
if (!this.do_unfollow(user_pid)) {
|
||||
$(event.target).attr("checked", "checked");
|
||||
}
|
||||
} else {
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], checklist, context])
|
||||
return this.ds_model.call(action_subscribe, [[this.view.datarecord.id], follower_ids, checklist, context])
|
||||
.then(this.proxy('read_value'));
|
||||
}
|
||||
},
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<div t-name="mail.followers.partner" class='oe_partner'>
|
||||
<img class="oe_mail_thumbnail oe_mail_frame" t-attf-src="{record.avatar_url}"/>
|
||||
<a t-attf-href="#model=res.partner&id=#{record.id}" t-att-title="record.name"><t t-esc="record.name"/></a>
|
||||
<span t-if="record.is_editable and (widget.records_length > 1)" class="oe_edit_subtype oe_e oe_hidden" title="Edit subscription" t-att-data-id="record.id">&</span>
|
||||
<span t-if="widget.view_is_editable" class="oe_remove_follower oe_e" title="Remove this follower" t-att-data-id="record.id">X</span>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -640,7 +640,7 @@ class test_mail(TestMailBase):
|
|||
})
|
||||
compose = mail_compose.browse(cr, uid, compose_id)
|
||||
|
||||
# D: Post the comment, get created message for each group
|
||||
# Do: Post the comment, get created message for each group
|
||||
mail_compose.send_mail(cr, user_raoul.id, [compose_id], context={
|
||||
'default_res_id': -1,
|
||||
'active_ids': [self.group_pigs_id, group_bird_id]
|
||||
|
@ -679,6 +679,37 @@ class test_mail(TestMailBase):
|
|||
self.assertEqual(set(bird_pids), set(test_pids),
|
||||
'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account')
|
||||
|
||||
# Do: Compose in mass_mail, coming from list_view, we have an active_domain that should be supported
|
||||
compose_id = mail_compose.create(cr, user_raoul.id,
|
||||
{
|
||||
'subject': _subject,
|
||||
'body': '${object.description}',
|
||||
'partner_ids': [(4, p_c_id), (4, p_d_id)],
|
||||
}, context={
|
||||
'default_composition_mode': 'mass_mail',
|
||||
'default_model': 'mail.group',
|
||||
'default_res_id': False,
|
||||
'active_ids': [self.group_pigs_id],
|
||||
'active_domain': [('name', 'in', ['Pigs', 'Bird'])],
|
||||
})
|
||||
compose = mail_compose.browse(cr, uid, compose_id)
|
||||
|
||||
# Do: Post the comment, get created message for each group
|
||||
mail_compose.send_mail(
|
||||
cr, user_raoul.id, [compose_id], context={
|
||||
'default_res_id': -1,
|
||||
'active_ids': [self.group_pigs_id, group_bird_id]
|
||||
})
|
||||
group_pigs.refresh()
|
||||
group_bird.refresh()
|
||||
message1 = group_pigs.message_ids[0]
|
||||
message2 = group_bird.message_ids[0]
|
||||
|
||||
# Test: Pigs and Bird did receive their message
|
||||
test_msg_ids = self.mail_message.search(cr, uid, [], limit=2)
|
||||
self.assertIn(message1.id, test_msg_ids, 'compose wizard: Pigs did not receive its mass mailing message')
|
||||
self.assertIn(message2.id, test_msg_ids, 'compose wizard: Bird did not receive its mass mailing message')
|
||||
|
||||
def test_30_needaction(self):
|
||||
""" Tests for mail.message needaction. """
|
||||
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
||||
|
|
|
@ -73,6 +73,11 @@ class mail_compose_message(osv.TransientModel):
|
|||
res_id = context.get('default_res_id', context.get('active_id'))
|
||||
message_id = context.get('default_parent_id', context.get('message_id', context.get('active_id')))
|
||||
active_ids = context.get('active_ids')
|
||||
if 'active_domain' in context: # not context.get() because we want to keep global [] domains
|
||||
result['use_active_domain'] = True
|
||||
result['active_domain'] = '%s' % context.get('active_domain')
|
||||
else:
|
||||
result['active_domain'] = ''
|
||||
|
||||
# get default values according to the composition mode
|
||||
if composition_mode == 'reply':
|
||||
|
@ -112,6 +117,8 @@ class mail_compose_message(osv.TransientModel):
|
|||
'partner_ids': fields.many2many('res.partner',
|
||||
'mail_compose_message_res_partner_rel',
|
||||
'wizard_id', 'partner_id', 'Additional contacts'),
|
||||
'use_active_domain': fields.boolean('Use active domain'),
|
||||
'active_domain': fields.char('Active domain', readonly=True),
|
||||
'post': fields.boolean('Post a copy in the document',
|
||||
help='Post a copy of the message on the document communication history.'),
|
||||
'notify': fields.boolean('Notify followers',
|
||||
|
@ -129,7 +136,6 @@ class mail_compose_message(osv.TransientModel):
|
|||
'body': lambda self, cr, uid, ctx={}: '',
|
||||
'subject': lambda self, cr, uid, ctx={}: False,
|
||||
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
||||
'notify': lambda self, cr, uid, ctx={}: False,
|
||||
'post': lambda self, cr, uid, ctx={}: True,
|
||||
'same_thread': lambda self, cr, uid, ctx={}: True,
|
||||
}
|
||||
|
@ -238,8 +244,14 @@ class mail_compose_message(osv.TransientModel):
|
|||
context['thread_model'] = wizard.model
|
||||
active_model_pool = self.pool['mail.thread']
|
||||
|
||||
# wizard works in batch mode: [res_id] or active_ids
|
||||
res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
|
||||
# wizard works in batch mode: [res_id] or active_ids or active_domain
|
||||
if mass_mail_mode and wizard.use_active_domain and wizard.model:
|
||||
res_ids = self.pool[wizard.model].search(cr, uid, eval(wizard.active_domain), context=context)
|
||||
elif mass_mail_mode and wizard.model and active_ids:
|
||||
res_ids = active_ids
|
||||
else:
|
||||
res_ids = [wizard.res_id]
|
||||
|
||||
for res_id in res_ids:
|
||||
# mail.message values, according to the wizard options
|
||||
post_values = {
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<field name="model" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<field name="mail_server_id" invisible="1"/>
|
||||
<field name="use_active_domain" invisible="1"/>
|
||||
<field name="active_domain" invisible="1"/>
|
||||
<!-- visible wizard -->
|
||||
<field name="email_from"
|
||||
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<record id="action_dummy" model="ir.actions.server">
|
||||
<field name="name">Dummy Action</field>
|
||||
<field name="name">Dummy Python Code</field>
|
||||
<field name="model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="state">dummy</field>
|
||||
<field name="code"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">True</field>
|
||||
<field eval="5" name="sequence"/>
|
||||
<field eval="True" name="condition"/>
|
||||
</record>
|
||||
|
|
|
@ -20,7 +20,7 @@ planning with the smart kanban and gantt views. Use the advanced analytics
|
|||
features to detect bottleneck in resources capacities and inventory locations.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=mrp" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -246,6 +246,7 @@ class mrp_production(osv.osv):
|
|||
""" Cancels work order if production order is canceled.
|
||||
@return: Super method
|
||||
"""
|
||||
workcenter_pool = self.pool.get('mrp.production.workcenter.line')
|
||||
obj = self.browse(cr, uid, ids,context=context)[0]
|
||||
for workcenter_line in obj.workcenter_lines:
|
||||
workcenter_pool.signal_button_cancel(cr, uid, [workcenter_line.id])
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
Organize yourself with efficient todo lists and notes. From personnal tasks to collaborative meeting minutes, increase your user's productivity by giving them the tools to prioritize their work, share their ideas and collaborate on documents.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=note" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="inherit_id" ref="project.view_task_form2"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="description" position="replace">
|
||||
<field name="description_pad" attrs="{'readonly':[('state','=','done')]}" widget="pad"/>
|
||||
<field name="description_pad" widget="pad"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -4,29 +4,31 @@ import simplejson
|
|||
import os
|
||||
import openerp
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.web.controllers.main import manifest_list, module_boot, html_template
|
||||
|
||||
class PointOfSaleController(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/pos'
|
||||
class PointOfSaleController(http.Controller):
|
||||
|
||||
@openerp.addons.web.http.httprequest
|
||||
def app(self, req, s_action=None, **kw):
|
||||
js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in manifest_list(req, None, 'js'))
|
||||
css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in manifest_list(req, None, 'css'))
|
||||
@http.route('/pos/app', type='http', auth='admin')
|
||||
def app(self):
|
||||
js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in manifest_list('js',db=request.db))
|
||||
css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in manifest_list('css',db=request.db))
|
||||
|
||||
cookie = req.httprequest.cookies.get("instance0|session_id")
|
||||
cookie = request.httprequest.cookies.get("instance0|session_id")
|
||||
session_id = cookie.replace("%22","")
|
||||
template = html_template.replace('<html','<html manifest="/pos/manifest?session_id=%s"'%session_id)
|
||||
template = html_template.replace('<html','<html manifest="/pos/manifest?session_id=%s"' % request.session_id)
|
||||
|
||||
r = template % {
|
||||
'js': js,
|
||||
'css': css,
|
||||
'modules': simplejson.dumps(module_boot(req)),
|
||||
'modules': simplejson.dumps(module_boot(request)),
|
||||
'init': 'var wc = new s.web.WebClient();wc.appendTo($(document.body));'
|
||||
}
|
||||
return r
|
||||
|
||||
@openerp.addons.web.http.httprequest
|
||||
def manifest(self, req, **kwargs):
|
||||
@http.route('/pos/manifest',type='http', auth='admin')
|
||||
def manifest(self):
|
||||
""" This generates a HTML5 cache manifest files that preloads the categories and products thumbnails
|
||||
and other ressources necessary for the point of sale to work offline """
|
||||
|
||||
|
@ -45,16 +47,16 @@ class PointOfSaleController(openerp.addons.web.http.Controller):
|
|||
imgdir = openerp.modules.get_module_resource('point_of_sale','static/src/img');
|
||||
load_css_img(imgdir,'/point_of_sale/static/src/img')
|
||||
|
||||
products = req.session.model('product.product')
|
||||
for p in products.search_read([('pos_categ_id','!=',False)], ['name']):
|
||||
products = request.registry.get('product.product')
|
||||
for p in products.search_read(request.cr, request.uid, [('pos_categ_id','!=',False)], ['name']):
|
||||
product_id = p['id']
|
||||
url = "/web/binary/image?session_id=%s&model=product.product&field=image&id=%s" % (req.session_id, product_id)
|
||||
url = "/web/binary/image?session_id=%s&model=product.product&field=image&id=%s" % (request.session_id, product_id)
|
||||
ml.append(url)
|
||||
|
||||
categories = req.session.model('pos.category')
|
||||
for c in categories.search_read([],['name']):
|
||||
categories = request.registry.get('pos.category')
|
||||
for c in categories.search_read(request.cr, request.uid, [], ['name']):
|
||||
category_id = c['id']
|
||||
url = "/web/binary/image?session_id=%s&model=pos.category&field=image&id=%s" % (req.session_id, category_id)
|
||||
url = "/web/binary/image?session_id=%s&model=pos.category&field=image&id=%s" % (request.session_id, category_id)
|
||||
ml.append(url)
|
||||
|
||||
ml += ["NETWORK:","*"]
|
||||
|
@ -62,108 +64,103 @@ class PointOfSaleController(openerp.addons.web.http.Controller):
|
|||
|
||||
return m
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def dispatch(self, request, iface, **kwargs):
|
||||
method = 'iface_%s' % iface
|
||||
return getattr(self, method)(request, **kwargs)
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def scan_item_success(self, request, ean):
|
||||
@http.route('/pos/scan_item_success', type='json', auth='admin')
|
||||
def scan_item_success(self, ean):
|
||||
"""
|
||||
A product has been scanned with success
|
||||
"""
|
||||
print 'scan_item_success: ' + str(ean)
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def scan_item_error_unrecognized(self, request, ean):
|
||||
@http.route('/pos/scan_item_error_unrecognized')
|
||||
def scan_item_error_unrecognized(self, ean):
|
||||
"""
|
||||
A product has been scanned without success
|
||||
"""
|
||||
print 'scan_item_error_unrecognized: ' + str(ean)
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def help_needed(self, request):
|
||||
@http.route('/pos/help_needed', type='json', auth='admin')
|
||||
def help_needed(self):
|
||||
"""
|
||||
The user wants an help (ex: light is on)
|
||||
"""
|
||||
print "help_needed"
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def help_canceled(self, request):
|
||||
@http.route('/pos/help_canceled', type='json', auth='admin')
|
||||
def help_canceled(self):
|
||||
"""
|
||||
The user stops the help request
|
||||
"""
|
||||
print "help_canceled"
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def weighting_start(self, request):
|
||||
@http.route('/pos/weighting_start', type='json', auth='admin')
|
||||
def weighting_start(self):
|
||||
print "weighting_start"
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def weighting_read_kg(self, request):
|
||||
@http.route('/pos/weighting_read_kg', type='json', auth='admin')
|
||||
def weighting_read_kg(self):
|
||||
print "weighting_read_kg"
|
||||
return 0.0
|
||||
return 3.14
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def weighting_end(self, request):
|
||||
@http.route('/pos/weighting_end', type='json', auth='admin')
|
||||
def weighting_end(self):
|
||||
print "weighting_end"
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def payment_request(self, request, price):
|
||||
@http.route('/pos/payment_request', type='json', auth='admin')
|
||||
def payment_request(self, price):
|
||||
"""
|
||||
The PoS will activate the method payment
|
||||
"""
|
||||
print "payment_request: price:"+str(price)
|
||||
return 'ok'
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def payment_status(self, request):
|
||||
@http.route('/pos/payment_status', type='json', auth='admin')
|
||||
def payment_status(self):
|
||||
print "payment_status"
|
||||
return { 'status':'waiting' }
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def payment_cancel(self, request):
|
||||
@http.route('/pos/payment_cancel', type='json', auth='admin')
|
||||
def payment_cancel(self):
|
||||
print "payment_cancel"
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def transaction_start(self, request):
|
||||
@http.route('/pos/transaction_start', type='json', auth='admin')
|
||||
def transaction_start(self):
|
||||
print 'transaction_start'
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def transaction_end(self, request):
|
||||
@http.route('/pos/transaction_end', type='json', auth='admin')
|
||||
def transaction_end(self):
|
||||
print 'transaction_end'
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def cashier_mode_activated(self, request):
|
||||
@http.route('/pos/cashier_mode_activated', type='json', auth='admin')
|
||||
def cashier_mode_activated(self):
|
||||
print 'cashier_mode_activated'
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def cashier_mode_deactivated(self, request):
|
||||
@http.route('/pos/cashier_mode_deactivated', type='json', auth='admin')
|
||||
def cashier_mode_deactivated(self):
|
||||
print 'cashier_mode_deactivated'
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def open_cashbox(self, request):
|
||||
@http.route('/pos/open_cashbox', type='json', auth='admin')
|
||||
def open_cashbox(self):
|
||||
print 'open_cashbox'
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def print_receipt(self, request, receipt):
|
||||
@http.route('/pos/print_receipt', type='json', auth='admin')
|
||||
def print_receipt(self, receipt):
|
||||
print 'print_receipt' + str(receipt)
|
||||
return
|
||||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def print_pdf_invoice(self, request, pdfinvoice):
|
||||
@http.route('/pos/print_pdf_invoice', type='json', auth='admin')
|
||||
def print_pdf_invoice(self, pdfinvoice):
|
||||
print 'print_pdf_invoice' + str(pdfinvoice)
|
||||
return
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ class pos_config(osv.osv):
|
|||
'iface_electronic_scale' : fields.boolean('Electronic Scale Interface'),
|
||||
'iface_vkeyboard' : fields.boolean('Virtual KeyBoard Interface'),
|
||||
'iface_print_via_proxy' : fields.boolean('Print via Proxy'),
|
||||
'iface_invoicing': fields.boolean('Invoicing',help='Enables invoice generation from the Point of Sale'),
|
||||
|
||||
'state' : fields.selection(POS_CONFIG_STATE, 'Status', required=True, readonly=True),
|
||||
'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence', readonly=True,
|
||||
|
@ -127,7 +128,8 @@ class pos_config(osv.osv):
|
|||
'warehouse_id': _default_warehouse,
|
||||
'journal_id': _default_sale_journal,
|
||||
'group_by' : True,
|
||||
'pricelist_id': _default_pricelist
|
||||
'pricelist_id': _default_pricelist,
|
||||
'iface_invoicing': True,
|
||||
}
|
||||
|
||||
def set_active(self, cr, uid, ids, context=None):
|
||||
|
@ -492,13 +494,17 @@ class pos_order(osv.osv):
|
|||
#_logger.info("orders: %r", orders)
|
||||
order_ids = []
|
||||
for tmp_order in orders:
|
||||
to_invoice = tmp_order['to_invoice']
|
||||
order = tmp_order['data']
|
||||
|
||||
|
||||
order_id = self.create(cr, uid, {
|
||||
'name': order['name'],
|
||||
'user_id': order['user_id'] or False,
|
||||
'session_id': order['pos_session_id'],
|
||||
'lines': order['lines'],
|
||||
'pos_reference':order['name']
|
||||
'pos_reference':order['name'],
|
||||
'partner_id': order['partner_id'] or False
|
||||
}, context)
|
||||
|
||||
for payments in order['statement_ids']:
|
||||
|
@ -529,6 +535,12 @@ class pos_order(osv.osv):
|
|||
}, context=context)
|
||||
order_ids.append(order_id)
|
||||
self.signal_paid(cr, uid, [order_id])
|
||||
|
||||
if to_invoice:
|
||||
self.action_invoice(cr, uid, [order_id], context)
|
||||
order_obj = self.browse(cr, uid, order_id, context)
|
||||
self.pool['account.invoice'].signal_invoice_open(cr, uid, [order_obj.invoice_id.id])
|
||||
|
||||
return order_ids
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
|
@ -881,6 +893,7 @@ class pos_order(osv.osv):
|
|||
inv_line_ref.create(cr, uid, inv_line, context=context)
|
||||
inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
|
||||
self.signal_invoice(cr, uid, [order.id])
|
||||
inv_ref.signal_validate(cr, uid, [inv_id])
|
||||
|
||||
if not inv_ids: return {}
|
||||
|
||||
|
|
|
@ -794,6 +794,7 @@
|
|||
<field name="iface_self_checkout" />
|
||||
<field name="iface_cashdrawer" />
|
||||
<field name="iface_payment_terminal" />
|
||||
<field name="iface_invoicing" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="iface_electronic_scale" />
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
consolidations amongst all shops without the hassle of integrating several applications.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
<a href="http://www.openerp.com/start?app=point_of_sale" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -291,10 +291,15 @@
|
|||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
width: 205px;
|
||||
max-height: 232px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.point-of-sale #paypad button {
|
||||
height: 50px;
|
||||
width: 208px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0px -6px 4px -2px;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
|
@ -302,6 +307,17 @@
|
|||
border-top: 1px solid #efefef;
|
||||
font-size: 14px;
|
||||
}
|
||||
.point-of-sale #paypad button, .point-of-sale #numpad button, .point-of-sale .popup button{
|
||||
position: relative;
|
||||
top: 0;
|
||||
-webkit-transition: top 150ms linear;
|
||||
-moz-transition: top 150ms linear;
|
||||
-ms-transition: top 150ms linear;
|
||||
transition: top 150ms linear;
|
||||
}
|
||||
.point-of-sale #paypad button:active, .point-of-sale #numpad button:active, .point-of-sale .popup button:active{
|
||||
top:3px;
|
||||
}
|
||||
.point-of-sale #paypad button:hover, .point-of-sale #numpad button:hover, .point-of-sale #numpad .selected-mode, .point-of-sale .popup button:hover {
|
||||
border: none;
|
||||
color: white;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -267,11 +267,21 @@ function openerp_pos_db(instance, module){
|
|||
return results;
|
||||
},
|
||||
add_order: function(order){
|
||||
var last_id = this.load('last_order_id',0);
|
||||
var order_id = order.uid;
|
||||
var orders = this.load('orders',[]);
|
||||
orders.push({id: last_id + 1, data: order});
|
||||
this.save('last_order_id',last_id+1);
|
||||
|
||||
// if the order was already stored, we overwrite its data
|
||||
for(var i = 0, len = orders.length; i < len; i++){
|
||||
if(orders[i].id === order_id){
|
||||
orders[i].data = order;
|
||||
this.save('orders',orders);
|
||||
return order_id;
|
||||
}
|
||||
}
|
||||
|
||||
orders.push({id: order_id, data: order});
|
||||
this.save('orders',orders);
|
||||
return order_id;
|
||||
},
|
||||
remove_order: function(order_id){
|
||||
var orders = this.load('orders',[]);
|
||||
|
@ -283,5 +293,14 @@ function openerp_pos_db(instance, module){
|
|||
get_orders: function(){
|
||||
return this.load('orders',[]);
|
||||
},
|
||||
get_order: function(order_id){
|
||||
var orders = this.get_orders();
|
||||
for(var i = 0, len = orders.length; i < len; i++){
|
||||
if(orders[i].id === order_id){
|
||||
return orders[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
|
||||
return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('company').currency_id[0]]]);
|
||||
}).then(function(currencies){
|
||||
console.log('Currency:',currencies[0]);
|
||||
self.set('currency',currencies[0]);
|
||||
|
||||
return self.fetch('product.uom', null, null);
|
||||
|
@ -145,7 +144,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
['name','journal_ids','warehouse_id','journal_id','pricelist_id',
|
||||
'iface_self_checkout', 'iface_led', 'iface_cashdrawer',
|
||||
'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard',
|
||||
'iface_print_via_proxy','iface_cashdrawer','state','sequence_id','session_ids'],
|
||||
'iface_print_via_proxy','iface_cashdrawer','iface_invoicing','state','sequence_id','session_ids'],
|
||||
[['id','=', self.get('pos_session').config_id[0]]]
|
||||
);
|
||||
}).then(function(configs){
|
||||
|
@ -156,6 +155,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
self.iface_vkeyboard = !!pos_config.iface_vkeyboard;
|
||||
self.iface_self_checkout = !!pos_config.iface_self_checkout;
|
||||
self.iface_cashdrawer = !!pos_config.iface_cashdrawer;
|
||||
self.iface_invoicing = !!pos_config.iface_invoicing;
|
||||
|
||||
return self.fetch('stock.warehouse',[],[['id','=',pos_config.warehouse_id[0]]]);
|
||||
}).then(function(shops){
|
||||
|
@ -240,12 +240,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
}
|
||||
},
|
||||
|
||||
// saves the order locally and try to send it to the backend. 'record' is a bizzarely defined JSON version of the Order
|
||||
push_order: function(record) {
|
||||
this.db.add_order(record);
|
||||
this.flush();
|
||||
},
|
||||
|
||||
//creates a new empty order and sets it as the current order
|
||||
add_new_order: function(){
|
||||
var order = new module.Order({pos:this});
|
||||
|
@ -253,45 +247,161 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
this.set('selectedOrder', order);
|
||||
},
|
||||
|
||||
// saves the order locally and try to send it to the backend.
|
||||
// it returns a deferred that succeeds after having tried to send the order and all the other pending orders.
|
||||
push_order: function(order) {
|
||||
var self = this;
|
||||
var order_id = this.db.add_order(order.export_as_JSON());
|
||||
var pushed = new $.Deferred();
|
||||
|
||||
this.set('nbr_pending_operations',self.db.get_orders().length);
|
||||
|
||||
this.flush_mutex.exec(function(){
|
||||
var flushed = self._flush_all_orders();
|
||||
|
||||
flushed.always(function(){
|
||||
pushed.resolve();
|
||||
});
|
||||
|
||||
return flushed;
|
||||
});
|
||||
return pushed;
|
||||
},
|
||||
|
||||
// saves the order locally and try to send it to the backend and make an invoice
|
||||
// returns a deferred that succeeds when the order has been posted and successfully generated
|
||||
// an invoice. This method can fail in various ways:
|
||||
// error-no-client: the order must have an associated partner_id. You can retry to make an invoice once
|
||||
// this error is solved
|
||||
// error-transfer: there was a connection error during the transfer. You can retry to make the invoice once
|
||||
// the network connection is up
|
||||
|
||||
push_and_invoice_order: function(order){
|
||||
var self = this;
|
||||
var invoiced = new $.Deferred();
|
||||
|
||||
if(!order.get_client()){
|
||||
invoiced.reject('error-no-client');
|
||||
return invoiced;
|
||||
}
|
||||
|
||||
var order_id = this.db.add_order(order.export_as_JSON());
|
||||
|
||||
this.set('nbr_pending_operations',self.db.get_orders().length);
|
||||
|
||||
this.flush_mutex.exec(function(){
|
||||
var done = new $.Deferred(); // holds the mutex
|
||||
|
||||
// send the order to the server
|
||||
// we have a 30 seconds timeout on this push.
|
||||
// FIXME: if the server takes more than 30 seconds to accept the order,
|
||||
// the client will believe it wasn't successfully sent, and very bad
|
||||
// things will happen as a duplicate will be sent next time
|
||||
// so we must make sure the server detects and ignores duplicated orders
|
||||
|
||||
var transfer = self._flush_order(order_id, {timeout:30000, to_invoice:true});
|
||||
|
||||
transfer.fail(function(){
|
||||
invoiced.reject('error-transfer');
|
||||
done.reject();
|
||||
});
|
||||
|
||||
// on success, get the order id generated by the server
|
||||
transfer.pipe(function(order_server_id){
|
||||
// generate the pdf and download it
|
||||
self.pos_widget.do_action('point_of_sale.pos_invoice_report',{additional_context:{
|
||||
active_ids:order_server_id,
|
||||
}});
|
||||
invoiced.resolve();
|
||||
done.resolve();
|
||||
});
|
||||
|
||||
return done;
|
||||
|
||||
});
|
||||
|
||||
return invoiced;
|
||||
},
|
||||
|
||||
// attemps to send all pending orders ( stored in the pos_db ) to the server,
|
||||
// and remove the successfully sent ones from the db once
|
||||
// it has been confirmed that they have been sent correctly.
|
||||
flush: function() {
|
||||
//TODO make the mutex work
|
||||
//this makes sure only one _int_flush is called at the same time
|
||||
/*
|
||||
return this.flush_mutex.exec(_.bind(function() {
|
||||
return this._flush(0);
|
||||
}, this));
|
||||
*/
|
||||
this._flush(0);
|
||||
var self = this;
|
||||
var flushed = new $.Deferred();
|
||||
|
||||
this.flush_mutex.exec(function(){
|
||||
var done = new $.Deferred();
|
||||
|
||||
self._flush_all_orders()
|
||||
.done( function(){ flushed.resolve();})
|
||||
.fail( function(){ flushed.reject(); })
|
||||
.always(function(){ done.resolve(); });
|
||||
|
||||
return done;
|
||||
});
|
||||
|
||||
return flushed;
|
||||
},
|
||||
// attempts to send an order of index 'index' in the list of order to send. The index
|
||||
// is used to skip orders that failed. do not call this method outside the mutex provided
|
||||
// by flush()
|
||||
_flush: function(index){
|
||||
|
||||
// attempts to send the locally stored order of id 'order_id'
|
||||
// the sending is asynchronous and can take some time to decide if it is successful or not
|
||||
// it is therefore important to only call this method from inside a mutex
|
||||
// this method returns a deferred indicating wether the sending was successful or not
|
||||
// there is a timeout parameter which is set to 2 seconds by default.
|
||||
_flush_order: function(order_id, options){
|
||||
var self = this;
|
||||
options = options || {};
|
||||
timeout = typeof options.timeout === 'number' ? options.timeout : 5000;
|
||||
|
||||
var order = this.db.get_order(order_id);
|
||||
order.to_invoice = options.to_invoice || false;
|
||||
|
||||
if(!order){
|
||||
// flushing a non existing order always fails
|
||||
return (new $.Deferred()).reject();
|
||||
}
|
||||
|
||||
// we try to send the order. shadow prevents a spinner if it takes too long. (unless we are sending an invoice,
|
||||
// then we want to notify the user that we are waiting on something )
|
||||
var rpc = (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{shadow: !options.to_invoice, timeout:timeout});
|
||||
|
||||
rpc.fail(function(unused,event){
|
||||
// prevent an error popup creation by the rpc failure
|
||||
// we want the failure to be silent as we send the orders in the background
|
||||
event.preventDefault();
|
||||
console.error('Failed to send order:',order);
|
||||
});
|
||||
|
||||
rpc.done(function(){
|
||||
self.db.remove_order(order_id);
|
||||
self.set('nbr_pending_operations',self.db.get_orders().length);
|
||||
});
|
||||
|
||||
return rpc;
|
||||
},
|
||||
|
||||
// attempts to send all the locally stored orders. As with _flush_order, it should only be
|
||||
// called from within a mutex.
|
||||
// this method returns a deferred that always succeeds when all orders have been tried to be sent,
|
||||
// even if none of them could actually be sent.
|
||||
_flush_all_orders: function(){
|
||||
var self = this;
|
||||
var orders = this.db.get_orders();
|
||||
self.set('nbr_pending_operations',orders.length);
|
||||
var tried_all = new $.Deferred();
|
||||
|
||||
var order = orders[index];
|
||||
if(!order){
|
||||
return;
|
||||
function rec_flush(index){
|
||||
if(index < orders.length){
|
||||
self._flush_order(orders[index].id).always(function(){
|
||||
rec_flush(index+1);
|
||||
})
|
||||
}else{
|
||||
tried_all.resolve();
|
||||
}
|
||||
}
|
||||
//try to push an order to the server
|
||||
// shadow : true is to prevent a spinner to appear in case of timeout
|
||||
(new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{ shadow:true })
|
||||
.fail(function(unused, event){
|
||||
//don't show error popup if it fails
|
||||
event.preventDefault();
|
||||
console.error('Failed to send order:',order);
|
||||
self._flush(index+1);
|
||||
})
|
||||
.done(function(){
|
||||
//remove from db if success
|
||||
self.db.remove_order(order.id);
|
||||
self._flush(index);
|
||||
});
|
||||
rec_flush(0);
|
||||
|
||||
return tried_all;
|
||||
},
|
||||
|
||||
scan_product: function(parsed_ean){
|
||||
|
@ -590,11 +700,12 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
module.Order = Backbone.Model.extend({
|
||||
initialize: function(attributes){
|
||||
Backbone.Model.prototype.initialize.apply(this, arguments);
|
||||
this.uid = this.generateUniqueId();
|
||||
this.set({
|
||||
creationDate: new Date(),
|
||||
orderLines: new module.OrderlineCollection(),
|
||||
paymentLines: new module.PaymentlineCollection(),
|
||||
name: "Order " + this.generateUniqueId(),
|
||||
name: "Order " + this.uid,
|
||||
client: null,
|
||||
});
|
||||
this.pos = attributes.pos;
|
||||
|
@ -770,7 +881,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
currency: this.pos.get('currency'),
|
||||
};
|
||||
},
|
||||
exportAsJSON: function() {
|
||||
export_as_JSON: function() {
|
||||
var orderLines, paymentLines;
|
||||
orderLines = [];
|
||||
(this.get('orderLines')).each(_.bind( function(item) {
|
||||
|
@ -789,8 +900,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
lines: orderLines,
|
||||
statement_ids: paymentLines,
|
||||
pos_session_id: this.pos.get('pos_session').id,
|
||||
partner_id: this.pos.get('client') ? this.pos.get('client').id : undefined,
|
||||
partner_id: this.get_client() ? this.get_client().id : false,
|
||||
user_id: this.pos.get('cashier') ? this.pos.get('cashier').id : this.pos.get('user').id,
|
||||
uid: this.uid,
|
||||
};
|
||||
},
|
||||
getSelectedLine: function(){
|
||||
|
|
|
@ -434,6 +434,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
template:'ErrorNegativePricePopupWidget',
|
||||
});
|
||||
|
||||
module.ErrorNoClientPopupWidget = module.ErrorPopupWidget.extend({
|
||||
template: 'ErrorNoClientPopupWidget',
|
||||
});
|
||||
|
||||
module.ErrorInvoiceTransferPopupWidget = module.ErrorPopupWidget.extend({
|
||||
template: 'ErrorInvoiceTransferPopupWidget',
|
||||
});
|
||||
|
||||
module.ScaleInviteScreenWidget = module.ScreenWidget.extend({
|
||||
template:'ScaleInviteScreenWidget',
|
||||
|
||||
|
@ -452,7 +460,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
clearInterval(this.intervalID);
|
||||
self.pos_widget.screen_selector.set_current_screen(self.next_screen);
|
||||
}
|
||||
},500);
|
||||
},100);
|
||||
|
||||
this.add_action_button({
|
||||
label: _t('Back'),
|
||||
|
@ -507,7 +515,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
self.weight = weight;
|
||||
self.renderElement();
|
||||
}
|
||||
},200);
|
||||
},100);
|
||||
},
|
||||
renderElement: function(){
|
||||
var self = this;
|
||||
|
@ -640,7 +648,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
var cashregister = selfCheckoutRegisters[0] || self.pos.get('cashRegisters').models[0];
|
||||
currentOrder.addPaymentLine(cashregister);
|
||||
self.pos.push_order(currentOrder.exportAsJSON())
|
||||
self.pos.push_order(currentOrder)
|
||||
currentOrder.destroy();
|
||||
self.pos.proxy.transaction_end();
|
||||
self.pos_widget.screen_selector.set_current_screen(self.next_screen);
|
||||
|
@ -808,19 +816,42 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this._super();
|
||||
var self = this;
|
||||
|
||||
this.add_action_button({
|
||||
var print_button = this.add_action_button({
|
||||
label: _t('Print'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/printer.png',
|
||||
click: function(){ self.print(); },
|
||||
});
|
||||
|
||||
this.add_action_button({
|
||||
var finish_button = this.add_action_button({
|
||||
label: _t('Next Order'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-next.png',
|
||||
click: function() { self.finishOrder(); },
|
||||
});
|
||||
|
||||
window.print();
|
||||
|
||||
// THIS IS THE HACK OF THE CENTURY
|
||||
//
|
||||
// The problem is that in chrome the print() is asynchronous and doesn't
|
||||
// execute until all rpc are finished. So it conflicts with the rpc used
|
||||
// to send the orders to the backend, and the user is able to go to the next
|
||||
// screen before the printing dialog is opened. The problem is that what's
|
||||
// printed is whatever is in the page when the dialog is opened and not when it's called,
|
||||
// and so you end up printing the product list instead of the receipt...
|
||||
//
|
||||
// Fixing this would need a re-architecturing
|
||||
// of the code to postpone sending of orders after printing.
|
||||
//
|
||||
// But since the print dialog also blocks the other asynchronous calls, the
|
||||
// button enabling in the setTimeout() is blocked until the printing dialog is
|
||||
// closed. But the timeout has to be big enough or else it doesn't work
|
||||
// 2 seconds is the same as the default timeout for sending orders and so the dialog
|
||||
// should have appeared before the timeout... so yeah that's not ultra reliable.
|
||||
|
||||
finish_button.set_disabled(true);
|
||||
setTimeout(function(){
|
||||
finish_button.set_disabled(false);
|
||||
}, 2000);
|
||||
},
|
||||
print: function() {
|
||||
window.print();
|
||||
|
@ -870,15 +901,15 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
this.set_numpad_state(this.pos_widget.numpad.state);
|
||||
|
||||
this.back_button = this.add_action_button({
|
||||
this.add_action_button({
|
||||
label: _t('Back'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
|
||||
click: function(){
|
||||
self.pos_widget.screen_selector.set_current_screen(self.back_screen);
|
||||
},
|
||||
});
|
||||
|
||||
this.validate_button = this.add_action_button({
|
||||
|
||||
this.add_action_button({
|
||||
label: _t('Validate'),
|
||||
name: 'validation',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/validate.png',
|
||||
|
@ -886,6 +917,17 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
self.validateCurrentOrder();
|
||||
},
|
||||
});
|
||||
|
||||
if(this.pos.iface_invoicing){
|
||||
this.add_action_button({
|
||||
label: 'Invoice',
|
||||
name: 'invoice',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/invoice.png',
|
||||
click: function(){
|
||||
self.validateCurrentOrder({invoice: true});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.updatePaymentSummary();
|
||||
this.line_refocus();
|
||||
|
@ -898,15 +940,44 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
back: function() {
|
||||
this.pos_widget.screen_selector.set_current_screen(self.back_screen);
|
||||
},
|
||||
validateCurrentOrder: function() {
|
||||
validateCurrentOrder: function(options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
|
||||
this.pos.push_order(currentOrder.exportAsJSON())
|
||||
if(this.pos.iface_print_via_proxy){
|
||||
this.pos.proxy.print_receipt(currentOrder.export_for_printing());
|
||||
this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen
|
||||
|
||||
if(options.invoice){
|
||||
// deactivate the validation button while we try to send the order
|
||||
this.pos_widget.action_bar.set_button_disabled('validation',true);
|
||||
this.pos_widget.action_bar.set_button_disabled('invoice',true);
|
||||
|
||||
var invoiced = this.pos.push_and_invoice_order(currentOrder);
|
||||
|
||||
invoiced.fail(function(error){
|
||||
if(error === 'error-no-client'){
|
||||
self.pos_widget.screen_selector.show_popup('error-no-client');
|
||||
}else{
|
||||
self.pos_widget.screen_selector.show_popup('error-invoice-transfer');
|
||||
}
|
||||
self.pos_widget.action_bar.set_button_disabled('validation',false);
|
||||
self.pos_widget.action_bar.set_button_disabled('invoice',false);
|
||||
});
|
||||
|
||||
invoiced.done(function(){
|
||||
self.pos_widget.action_bar.set_button_disabled('validation',false);
|
||||
self.pos_widget.action_bar.set_button_disabled('invoice',false);
|
||||
self.pos.get('selectedOrder').destroy();
|
||||
});
|
||||
|
||||
}else{
|
||||
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
||||
this.pos.push_order(currentOrder)
|
||||
if(this.pos.iface_print_via_proxy){
|
||||
this.pos.proxy.print_receipt(currentOrder.export_for_printing());
|
||||
this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen
|
||||
}else{
|
||||
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
||||
}
|
||||
}
|
||||
},
|
||||
bindPaymentLineEvents: function() {
|
||||
|
@ -985,6 +1056,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
if(this.pos_widget.action_bar){
|
||||
this.pos_widget.action_bar.set_button_disabled('validation', remaining > 0.000001);
|
||||
this.pos_widget.action_bar.set_button_disabled('invoice', remaining > 0.000001);
|
||||
}
|
||||
},
|
||||
set_numpad_state: function(numpadState) {
|
||||
|
|
|
@ -838,6 +838,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
instance.web.blockUI();
|
||||
|
||||
this.pos = new module.PosModel(this.session);
|
||||
this.pos.pos_widget = this;
|
||||
this.pos_widget = this; //So that pos_widget's childs have pos_widget set automatically
|
||||
|
||||
this.numpad_visible = true;
|
||||
|
@ -952,6 +953,12 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.error_negative_price_popup = new module.ErrorNegativePricePopupWidget(this, {});
|
||||
this.error_negative_price_popup.appendTo($('.point-of-sale'));
|
||||
|
||||
this.error_no_client_popup = new module.ErrorNoClientPopupWidget(this, {});
|
||||
this.error_no_client_popup.appendTo($('.point-of-sale'));
|
||||
|
||||
this.error_invoice_transfer_popup = new module.ErrorInvoiceTransferPopupWidget(this, {});
|
||||
this.error_invoice_transfer_popup.appendTo($('.point-of-sale'));
|
||||
|
||||
// -------- Misc ---------
|
||||
|
||||
this.notification = new module.SynchNotificationWidget(this,{});
|
||||
|
@ -1013,6 +1020,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
'error-session': this.error_session_popup,
|
||||
'error-negative-price': this.error_negative_price_popup,
|
||||
'choose-receipt': this.choose_receipt_popup,
|
||||
'error-no-client': this.error_no_client_popup,
|
||||
'error-invoice-transfer': this.error_invoice_transfer_popup,
|
||||
},
|
||||
default_client_screen: 'welcome',
|
||||
default_cashier_screen: 'products',
|
||||
|
|
|
@ -336,11 +336,11 @@
|
|||
<div class="modal-dialog">
|
||||
<div class="popup popup-help">
|
||||
<p class="message">The scanned product was not recognized<br /> Please wait, a cashier is on the way</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="button">
|
||||
Ok
|
||||
<div class="footer">
|
||||
<div class="button">
|
||||
Ok
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
@ -361,6 +361,33 @@
|
|||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ErrorNoClientPopupWidget">
|
||||
<div class="modal-dialog">
|
||||
<div class="popup popup-help">
|
||||
<p class="message">An anonymous order cannot be invoiced</p>
|
||||
<div class="footer">
|
||||
<div class="button">
|
||||
Ok
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ErrorInvoiceTransferPopupWidget">
|
||||
<div class="modal-dialog">
|
||||
<div class="popup popup-help">
|
||||
<p class="message">The Order could not be sent to the server for invoicing. Invoices cannot be generated
|
||||
in offline mode. Please check your internet connection and try again.</p>
|
||||
<div class="footer">
|
||||
<div class="button">
|
||||
Ok
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ErrorPopupWidget">
|
||||
<div class="modal-dialog">
|
||||
<div class="popup popup-help">
|
||||
|
@ -538,7 +565,6 @@
|
|||
<button class="paypad-button" t-att-cash-register-id="widget.cashRegister.get('id')">
|
||||
<t t-esc="widget.cashRegister.get('journal').name"/>
|
||||
</button>
|
||||
<br />
|
||||
</t>
|
||||
|
||||
<t t-name="OrderButtonWidget">
|
||||
|
|
|
@ -19,35 +19,17 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.project.tests.test_project_base import TestProjectBase
|
||||
from openerp.osv.orm import except_orm
|
||||
from openerp.tests import common
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestPortalProject(common.TransactionCase):
|
||||
class TestPortalProjectBase(TestProjectBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortalProject, self).setUp()
|
||||
super(TestPortalProjectBase, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Useful models
|
||||
self.project_project = self.registry('project.project')
|
||||
self.project_task = self.registry('project.task')
|
||||
self.res_users = self.registry('res.users')
|
||||
self.res_partner = self.registry('res.partner')
|
||||
|
||||
# Find Employee group
|
||||
group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
|
||||
self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
|
||||
|
||||
# Find Project User group
|
||||
group_project_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_user')
|
||||
self.group_project_user_id = group_project_user_ref and group_project_user_ref[1] or False
|
||||
|
||||
# Find Project Manager group
|
||||
group_project_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_manager')
|
||||
self.group_project_manager_id = group_project_manager_ref and group_project_manager_ref[1] or False
|
||||
|
||||
# Find Portal group
|
||||
group_portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal')
|
||||
self.group_portal_id = group_portal_ref and group_portal_ref[1] or False
|
||||
|
@ -56,62 +38,39 @@ class TestPortalProject(common.TransactionCase):
|
|||
group_public_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_public')
|
||||
self.group_public_id = group_public_ref and group_public_ref[1] or False
|
||||
|
||||
# Test users to use through the various tests
|
||||
self.user_alfred_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Alfred EmployeeUser',
|
||||
'login': 'alfred',
|
||||
'alias_name': 'alfred',
|
||||
'groups_id': [(6, 0, [self.group_employee_id, self.group_project_user_id])]
|
||||
})
|
||||
self.user_bert_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Bert Nobody',
|
||||
'login': 'bert',
|
||||
'alias_name': 'bert',
|
||||
'groups_id': [(6, 0, [])]
|
||||
})
|
||||
self.user_chell_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Chell Portal',
|
||||
'login': 'chell',
|
||||
'alias_name': 'chell',
|
||||
'groups_id': [(6, 0, [self.group_portal_id])]
|
||||
})
|
||||
self.user_donovan_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Donovan Public',
|
||||
'login': 'donovan',
|
||||
'alias_name': 'donovan',
|
||||
'groups_id': [(6, 0, [self.group_public_id])]
|
||||
})
|
||||
self.user_ernest_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Ernest Manager',
|
||||
'login': 'ernest',
|
||||
'alias_name': 'ernest',
|
||||
'groups_id': [(6, 0, [self.group_project_manager_id])]
|
||||
})
|
||||
# # Test users to use through the various tests
|
||||
self.user_portal_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Chell Portal',
|
||||
'login': 'chell',
|
||||
'alias_name': 'chell',
|
||||
'groups_id': [(6, 0, [self.group_portal_id])]
|
||||
})
|
||||
self.user_public_id = self.res_users.create(cr, uid, {
|
||||
'name': 'Donovan Public',
|
||||
'login': 'donovan',
|
||||
'alias_name': 'donovan',
|
||||
'groups_id': [(6, 0, [self.group_public_id])]
|
||||
})
|
||||
|
||||
# Test 'Pigs' project
|
||||
self.project_pigs_id = self.project_project.create(cr, uid,
|
||||
{'name': 'Pigs', 'privacy_visibility': 'public'},
|
||||
{'mail_create_nolog': True})
|
||||
self.project_pigs_id = self.project_project.create(cr, uid, {
|
||||
'name': 'Pigs', 'privacy_visibility': 'public'}, {'mail_create_nolog': True})
|
||||
# Various test tasks
|
||||
self.task_1_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_2_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_3_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_4_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test4', 'user_id': self.user_alfred_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_5_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test5', 'user_id': self.user_chell_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_6_id = self.project_task.create(cr, uid,
|
||||
{'name': 'Test6', 'user_id': self.user_donovan_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.task_1_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_2_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_3_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_4_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_5_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.task_6_id = self.project_task.create(cr, uid, {
|
||||
'name': 'Test6', 'user_id': self.user_public_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
|
||||
|
||||
class TestPortalProject(TestPortalProjectBase):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
|
||||
def test_00_project_access_rights(self):
|
||||
""" Test basic project access rights, for project and portal_project """
|
||||
|
@ -122,53 +81,47 @@ class TestPortalProject(common.TransactionCase):
|
|||
# ----------------------------------------
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_projectuser_id, pigs_id, ['name'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_alfred_id, task_ids, ['name'])
|
||||
self.project_task.read(cr, self.user_projectuser_id, task_ids, ['name'])
|
||||
# Test: all project tasks writable
|
||||
self.project_task.write(cr, self.user_alfred_id, task_ids, {'description': 'TestDescription'})
|
||||
self.project_task.write(cr, self.user_projectuser_id, task_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_bert_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_none_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
self.assertRaises(except_orm, self.project_task.search,
|
||||
cr, self.user_bert_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(except_orm, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
# Test: no project task readable
|
||||
self.assertRaises(except_orm, self.project_task.read,
|
||||
cr, self.user_bert_id, task_ids, ['name'])
|
||||
self.assertRaises(except_orm, self.project_task.read, cr, self.user_none_id, task_ids, ['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(except_orm, self.project_task.write,
|
||||
cr, self.user_bert_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(except_orm, self.project_task.write, cr, self.user_none_id, task_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
self.project_project.read(cr, self.user_chell_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_portal_id, pigs_id, ['name'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
'access rights: project user cannot see all tasks of a public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_chell_id, task_ids, ['name'])
|
||||
self.project_task.read(cr, self.user_portal_id, task_ids, ['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(except_orm, self.project_task.write,
|
||||
cr, self.user_chell_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(except_orm, self.project_task.write, cr, self.user_portal_id, task_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Donovan reads project -> ok (public ok public)
|
||||
self.project_project.read(cr, self.user_donovan_id, pigs_id, ['name'])
|
||||
# Do: Donovan reads project -> ok (public)
|
||||
self.project_project.read(cr, self.user_public_id, pigs_id, ['name'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: public user cannot see all tasks of a public project')
|
||||
'access rights: public user cannot see all tasks of a public project')
|
||||
# Test: all project tasks readable
|
||||
self.project_task.read(cr, self.user_donovan_id, task_ids, ['name'])
|
||||
self.project_task.read(cr, self.user_public_id, task_ids, ['name'])
|
||||
# Test: no project task writable
|
||||
self.assertRaises(except_orm, self.project_task.write,
|
||||
cr, self.user_donovan_id, task_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(except_orm, self.project_task.write, cr, self.user_public_id, task_ids, {'description': 'TestDescription'})
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: portal project
|
||||
|
@ -176,39 +129,36 @@ class TestPortalProject(common.TransactionCase):
|
|||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'})
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_projectuser_id, pigs_id, ['name'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of a portal project')
|
||||
'access rights: project user cannot see all tasks of a portal project')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_bert_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_none_id, pigs_id, ['name'])
|
||||
# Test: no project task searchable
|
||||
self.assertRaises(except_orm, self.project_task.search,
|
||||
cr, self.user_bert_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(except_orm, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
|
||||
# Data: task follower
|
||||
self.project_task.message_subscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id])
|
||||
self.project_task.message_subscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
self.project_project.read(cr, self.user_chell_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_portal_id, pigs_id, ['name'])
|
||||
# Test: only followed project tasks visible + assigned
|
||||
task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_3_id, self.task_5_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: portal user should see the followed tasks of a portal project')
|
||||
'access rights: portal user should see the followed tasks of a portal project')
|
||||
|
||||
# Do: Donovan reads project -> ko (public ko portal)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_donovan_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of a portal project')
|
||||
|
||||
# Data: task follower cleaning
|
||||
self.project_task.message_unsubscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id])
|
||||
self.project_task.message_unsubscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE3: employee project
|
||||
|
@ -216,29 +166,26 @@ class TestPortalProject(common.TransactionCase):
|
|||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'})
|
||||
|
||||
# Do: Alfred reads project -> ok (employee ok employee)
|
||||
self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_projectuser_id, pigs_id, ['name'])
|
||||
# Test: all project tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: project user cannot see all tasks of an employees project')
|
||||
'access rights: project user cannot see all tasks of an employees project')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_bert_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_none_id, pigs_id, ['name'])
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_chell_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, pigs_id, ['name'])
|
||||
# Test: no project task visible + assigned
|
||||
task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: portal user should not see tasks of an employees project, even if assigned')
|
||||
|
||||
# Do: Donovan reads project -> ko (public ko employee)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_donovan_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of an employees project')
|
||||
|
||||
# ----------------------------------------
|
||||
|
@ -247,54 +194,49 @@ class TestPortalProject(common.TransactionCase):
|
|||
self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'})
|
||||
|
||||
# Do: Alfred reads project -> ko (employee ko followers)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_alfred_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_projectuser_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_4_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: employee user should not see tasks of a not-followed followers project, only assigned')
|
||||
'access rights: employee user should not see tasks of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_bert_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_none_id, pigs_id, ['name'])
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_chell_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_5_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: portal user should not see tasks of a not-followed followers project, only assigned')
|
||||
'access rights: portal user should not see tasks of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Donovan reads project -> ko (public ko employee)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_donovan_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, pigs_id, ['name'])
|
||||
# Test: no project task visible
|
||||
task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(task_ids, 'access rights: public user should not see tasks of a followers project')
|
||||
|
||||
# Data: subscribe Alfred, Chell and Donovan as follower
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_alfred_id, self.user_chell_id, self.user_donovan_id])
|
||||
self.project_task.message_subscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id, self.user_alfred_id])
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_public_id])
|
||||
self.project_task.message_subscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id, self.user_projectuser_id])
|
||||
|
||||
# Do: Alfred reads project -> ok (follower ok followers)
|
||||
self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_projectuser_id, pigs_id, ['name'])
|
||||
# Test: followed + assigned tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_3_id, self.task_4_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: employee user should not see followed + assigned tasks of a follower project')
|
||||
'access rights: employee user should not see followed + assigned tasks of a follower project')
|
||||
|
||||
# Do: Chell reads project -> ok (follower ok follower)
|
||||
self.project_project.read(cr, self.user_chell_id, pigs_id, ['name'])
|
||||
self.project_project.read(cr, self.user_portal_id, pigs_id, ['name'])
|
||||
# Test: followed + assigned tasks visible
|
||||
task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_task_ids = set([self.task_1_id, self.task_3_id, self.task_5_id])
|
||||
self.assertEqual(set(task_ids), test_task_ids,
|
||||
'access rights: employee user should not see followed + assigned tasks of a follower project')
|
||||
'access rights: employee user should not see followed + assigned tasks of a follower project')
|
||||
|
||||
# Do: Donovan reads project -> ko (public ko follower even if follower)
|
||||
self.assertRaises(except_orm, self.project_project.read,
|
||||
cr, self.user_donovan_id, pigs_id, ['name'])
|
||||
self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, pigs_id, ['name'])
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
<div><field name="categ_ids" widget="many2many_tags" class="oe_left"/></div>
|
||||
<div class="oe_text_right">
|
||||
<h1><field name="state" readonly="1"/></h1>
|
||||
<h1><field name="stage_id" readonly="1"/></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -19,40 +19,36 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.portal_project.tests.test_access_rights import TestPortalProject
|
||||
from openerp.addons.portal_project.tests.test_access_rights import TestPortalProjectBase
|
||||
from openerp.osv.orm import except_orm
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestPortalIssueProject(TestPortalProject):
|
||||
class TestPortalProjectBase(TestPortalProjectBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortalIssueProject, self).setUp()
|
||||
super(TestPortalProjectBase, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
# Useful models
|
||||
self.project_issue = self.registry('project.issue')
|
||||
|
||||
# Various test issues
|
||||
self.issue_1_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_2_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_3_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_4_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test4', 'user_id': self.user_alfred_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_5_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test5', 'user_id': self.user_chell_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_6_id = self.project_issue.create(cr, uid,
|
||||
{'name': 'Test6', 'user_id': self.user_donovan_id, 'project_id': self.project_pigs_id},
|
||||
{'mail_create_nolog': True})
|
||||
self.issue_1_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_2_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_3_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_4_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_5_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
self.issue_6_id = self.project_issue.create(cr, uid, {
|
||||
'name': 'Test6', 'user_id': self.user_anonymous_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
|
||||
|
||||
|
||||
class TestPortalIssue(TestPortalProjectBase):
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
|
||||
def test_00_project_access_rights(self):
|
||||
""" Test basic project access rights, for project and portal_project """
|
||||
|
@ -64,42 +60,38 @@ class TestPortalIssueProject(TestPortalProject):
|
|||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
# Test: all project issues readable
|
||||
self.project_issue.read(cr, self.user_alfred_id, issue_ids, ['name'])
|
||||
self.project_issue.read(cr, self.user_projectuser_id, issue_ids, ['name'])
|
||||
# Test: all project issues writable
|
||||
self.project_issue.write(cr, self.user_alfred_id, issue_ids, {'description': 'TestDescription'})
|
||||
self.project_issue.write(cr, self.user_projectuser_id, issue_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
# Test: no project issue visible
|
||||
self.assertRaises(except_orm, self.project_issue.search,
|
||||
cr, self.user_bert_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(except_orm, self.project_issue.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
# Test: no project issue readable
|
||||
self.assertRaises(except_orm, self.project_issue.read,
|
||||
cr, self.user_bert_id, issue_ids, ['name'])
|
||||
self.assertRaises(except_orm, self.project_issue.read, cr, self.user_none_id, issue_ids, ['name'])
|
||||
# Test: no project issue writable
|
||||
self.assertRaises(except_orm, self.project_issue.write,
|
||||
cr, self.user_bert_id, issue_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(except_orm, self.project_issue.write, cr, self.user_none_id, issue_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
# Test: all project issues readable
|
||||
self.project_issue.read(cr, self.user_chell_id, issue_ids, ['name'])
|
||||
self.project_issue.read(cr, self.user_portal_id, issue_ids, ['name'])
|
||||
# Test: no project issue writable
|
||||
self.assertRaises(except_orm, self.project_issue.write,
|
||||
cr, self.user_chell_id, issue_ids, {'description': 'TestDescription'})
|
||||
self.assertRaises(except_orm, self.project_issue.write, cr, self.user_portal_id, issue_ids, {'description': 'TestDescription'})
|
||||
|
||||
# Do: Donovan reads project -> ok (public ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_anonymous_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
'access rights: project user cannot see all issues of a public project')
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE2: portal project
|
||||
|
@ -108,27 +100,26 @@ class TestPortalIssueProject(TestPortalProject):
|
|||
|
||||
# Do: Alfred reads project -> ok (employee ok public)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of a portal project')
|
||||
'access rights: project user cannot see all issues of a portal project')
|
||||
|
||||
# Do: Bert reads project -> crash, no group
|
||||
# Test: no project issue searchable
|
||||
self.assertRaises(except_orm, self.project_issue.search,
|
||||
cr, self.user_bert_id, [('project_id', '=', pigs_id)])
|
||||
self.assertRaises(except_orm, self.project_issue.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
|
||||
|
||||
# Data: issue follower
|
||||
self.project_issue.message_subscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id])
|
||||
self.project_issue.message_subscribe_users(cr, self.user_projectuser_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id])
|
||||
|
||||
# Do: Chell reads project -> ok (portal ok public)
|
||||
# Test: only followed project issues visible + assigned
|
||||
issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: portal user should see the followed issues of a portal project')
|
||||
'access rights: portal user should see the followed issues of a portal project')
|
||||
|
||||
# Data: issue follower cleaning
|
||||
self.project_issue.message_unsubscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id])
|
||||
self.project_issue.message_unsubscribe_users(cr, self.user_projectuser_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id])
|
||||
|
||||
# ----------------------------------------
|
||||
# CASE3: employee project
|
||||
|
@ -137,14 +128,14 @@ class TestPortalIssueProject(TestPortalProject):
|
|||
|
||||
# Do: Alfred reads project -> ok (employee ok employee)
|
||||
# Test: all project issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: project user cannot see all issues of an employees project')
|
||||
'access rights: project user cannot see all issues of an employees project')
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
# Test: no project issue visible + assigned
|
||||
issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
self.assertFalse(issue_ids, 'access rights: portal user should not see issues of an employees project, even if assigned')
|
||||
|
||||
# ----------------------------------------
|
||||
|
@ -154,32 +145,32 @@ class TestPortalIssueProject(TestPortalProject):
|
|||
|
||||
# Do: Alfred reads project -> ko (employee ko followers)
|
||||
# Test: no project issue visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_4_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: employee user should not see issues of a not-followed followers project, only assigned')
|
||||
'access rights: employee user should not see issues of a not-followed followers project, only assigned')
|
||||
|
||||
# Do: Chell reads project -> ko (portal ko employee)
|
||||
# Test: no project issue visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: portal user should not see issues of a not-followed followers project, only assigned')
|
||||
'access rights: portal user should not see issues of a not-followed followers project, only assigned')
|
||||
|
||||
# Data: subscribe Alfred, Chell and Donovan as follower
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_alfred_id, self.user_chell_id, self.user_donovan_id])
|
||||
self.project_issue.message_subscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id, self.user_alfred_id])
|
||||
self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_anonymous_id])
|
||||
self.project_issue.message_subscribe_users(cr, self.user_projectuser_id, [self.issue_1_id, self.issue_3_id], [self.user_portal_id, self.user_projectuser_id])
|
||||
|
||||
# Do: Alfred reads project -> ok (follower ok followers)
|
||||
# Test: followed + assigned issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_4_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
|
||||
# Do: Chell reads project -> ok (follower ok follower)
|
||||
# Test: followed + assigned issues visible
|
||||
issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)])
|
||||
issue_ids = self.project_issue.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
|
||||
test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id])
|
||||
self.assertEqual(set(issue_ids), test_issue_ids,
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
'access rights: employee user should not see followed + assigned issues of a follower project')
|
||||
|
|
|
@ -376,11 +376,26 @@ class product_pricelist_item(osv.osv):
|
|||
result.append((-2, _('Supplier Prices on the product form')))
|
||||
return result
|
||||
|
||||
# Added default function to fetch the Price type Based on Pricelist type.
|
||||
def _get_default_base(self, cr, uid, fields, context=None):
|
||||
product_price_type_obj = self.pool.get('product.price.type')
|
||||
if fields.get('type') == 'purchase':
|
||||
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field', '=', 'standard_price')], context=context)
|
||||
elif fields.get('type') == 'sale':
|
||||
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context=context)
|
||||
else:
|
||||
return -1
|
||||
if not product_price_type_ids:
|
||||
return False
|
||||
else:
|
||||
pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
|
||||
return pricetype.id
|
||||
|
||||
_name = "product.pricelist.item"
|
||||
_description = "Pricelist item"
|
||||
_order = "sequence, min_quantity desc"
|
||||
_defaults = {
|
||||
'base': lambda *a: -1,
|
||||
'base': _get_default_base,
|
||||
'min_quantity': lambda *a: 0,
|
||||
'sequence': lambda *a: 5,
|
||||
'price_discount': lambda *a: 0,
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<field name="currency_id" groups="base.group_multi_currency"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
</group>
|
||||
<field name="version_id">
|
||||
<field name="version_id" context="{'type':type}">
|
||||
<form string="Pricelist Version" version="7.0">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
|
@ -160,7 +160,7 @@
|
|||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
</group>
|
||||
<field name="items_id"/>
|
||||
<field name="items_id" context="{'type':type}"/>
|
||||
</form>
|
||||
<tree string="Pricelist Version">
|
||||
<field name="name"/>
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
],
|
||||
'depends': [
|
||||
'base_setup',
|
||||
'base_status',
|
||||
'product',
|
||||
'analytic',
|
||||
'board',
|
||||
|
@ -66,7 +65,6 @@ Dashboard / Reports for Project Management will include:
|
|||
'data': [
|
||||
'security/project_security.xml',
|
||||
'wizard/project_task_delegate_view.xml',
|
||||
'wizard/project_task_reevaluate_view.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'project_data.xml',
|
||||
'project_view.xml',
|
||||
|
@ -79,9 +77,6 @@ Dashboard / Reports for Project Management will include:
|
|||
],
|
||||
'demo': ['project_demo.xml'],
|
||||
'test': [
|
||||
'test/project_demo.yml',
|
||||
'test/project_process.yml',
|
||||
'test/task_process.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
<field name="effective_hours" widget="float_time"/>
|
||||
<field name="progress" widget="progressbar"/>
|
||||
<field name="stage_id" invisible="context.get('set_visible',False)"/>
|
||||
<field name="state" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -26,7 +25,7 @@
|
|||
<field name="res_model">project.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('user_id','=',uid),('state','not in',('cancel','done'))]</field>
|
||||
<field name="domain">[('user_id', '=', uid), ('stage_id.fold', '!=', True)]</field>
|
||||
<field name="view_id" ref="view_task_tree"/>
|
||||
</record>
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue