[MERGE]: Merged with trunk-addons.
bzr revid: uco@tinyerp.com-20110915112517-e8jl74b7n40zv9iv
This commit is contained in:
commit
12be0d9230
|
@ -115,7 +115,7 @@
|
|||
<field name="model">account.invoice</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in ('cancel')" string="Invoice">
|
||||
<tree colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'" string="Invoice">
|
||||
<field name="date_invoice"/>
|
||||
<field name="number"/>
|
||||
<field name="partner_id" groups="base.group_user"/>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<field name="model">account.fiscalyear</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done') " string="Fiscalyear">
|
||||
<tree colors="blue:state == 'draft';gray:state == 'done' " string="Fiscalyear">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
|
@ -111,7 +111,7 @@
|
|||
<field name="model">account.period</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done') " string="Period">
|
||||
<tree colors="blue:state == 'draft';gray:state == 'done' " string="Period">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="date_start"/>
|
||||
|
@ -228,7 +228,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:type in ('view');black:type in ('other','receivable','payable','consolidation');gray:type in ('closed')" string="Chart of accounts" toolbar="1" >
|
||||
<tree colors="blue:type == 'view';black:type in ('other','receivable','payable','consolidation');gray:type == 'closed'" string="Chart of accounts" toolbar="1" >
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
|
@ -271,7 +271,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:type in ('view');black:type in ('other','receivable','payable','consolidation');gray:type in ('closed')" string="Chart of accounts" toolbar="1" >
|
||||
<tree colors="blue:type == 'view';black:type in ('other','receivable','payable','consolidation');gray:type == 'closed'" string="Chart of accounts" toolbar="1" >
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="debit"/>
|
||||
|
@ -776,7 +776,7 @@
|
|||
<field name="model">account.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" string="Journal Entries">
|
||||
<tree colors="blue:state == 'draft';black:state == 'posted'" string="Journal Entries">
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="date"/>
|
||||
|
@ -1007,7 +1007,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:state in ('draft');black:state in ('valid')" string="Journal Items" editable="top" on_write="on_create_write">
|
||||
<tree colors="red:state == 'draft';black:state == 'valid'" string="Journal Items" editable="top" on_write="on_create_write">
|
||||
<field name="date"/>
|
||||
<field name="period_id"/>
|
||||
<field name="move_id"/>
|
||||
|
@ -1290,7 +1290,7 @@
|
|||
<field name="model">account.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" string="Journal Entries">
|
||||
<tree colors="blue:state == 'draft';black:state == 'posted'" string="Journal Entries">
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="date"/>
|
||||
|
@ -1395,7 +1395,7 @@
|
|||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" editable="top" string="Journal Items">
|
||||
<tree colors="blue:state == 'draft';black:state == 'posted'" editable="top" string="Journal Items">
|
||||
<field name="ref"/>
|
||||
<field name="invoice"/>
|
||||
<field name="name"/>
|
||||
|
@ -1560,7 +1560,7 @@
|
|||
<field name="model">account.journal.period</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done');black:state in ('printed')" string="Journals">
|
||||
<tree colors="blue:state == 'draft';gray:state == 'done';black:state == 'printed'" string="Journals">
|
||||
<field icon="icon" name="fiscalyear_id"/>
|
||||
<field name="period_id"/>
|
||||
<field name="journal_id"/>
|
||||
|
@ -1816,7 +1816,7 @@
|
|||
<field name="model">account.subscription</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done');black:state in ('running')" string="Entry Subscription">
|
||||
<tree colors="blue:state == 'draft';gray:state == 'done';black:state == 'running'" string="Entry Subscription">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="ref"/>
|
||||
|
@ -1946,7 +1946,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:state in ('draft');black:state in ('valid')" string="Journal Items">
|
||||
<tree colors="red:state == 'draft';black:state == 'valid'" string="Journal Items">
|
||||
<field name="date"/>
|
||||
<field name="move_id"/>
|
||||
<field name="statement_id" string="St."/>
|
||||
|
@ -2426,10 +2426,10 @@
|
|||
<field name="model_id" ref="base.model_ir_actions_todo"/>
|
||||
<field eval="5" name="sequence"/>
|
||||
<field name="code">
|
||||
act_window_ids = self.pool.get('ir.actions.act_window').search(cr, uid,[('name', 'in', ('Accounting Chart Configuration', 'Generate Chart of Accounts from a Chart Template'))], context=context)
|
||||
todo_ids = self.pool.get('ir.actions.todo').search(cr, uid, [('action_id', 'in', act_window_ids)], context=context)
|
||||
self.pool.get('ir.actions.todo').write(cr, uid, todo_ids, {'state':'open'}, context=context)
|
||||
action = self.pool.get('res.config').next(cr, uid, [], context)
|
||||
act_window_ids = pool.get('ir.actions.act_window').search(cr, uid,[('name', 'in', ('Accounting Chart Configuration', 'Generate Chart of Accounts from a Chart Template'))], context=context)
|
||||
todo_ids = pool.get('ir.actions.todo').search(cr, uid, [('action_id', 'in', act_window_ids)], context=context)
|
||||
pool.get('ir.actions.todo').write(cr, uid, todo_ids, {'state':'open'}, context=context)
|
||||
action = pool.get('res.config').next(cr, uid, [], context)
|
||||
</field>
|
||||
<field name="name">New Company Financial Setting</field>
|
||||
</record>
|
||||
|
@ -2530,7 +2530,7 @@ action = self.pool.get('res.config').next(cr, uid, [], context)
|
|||
<field name="model">account.bank.statement</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:balance_end_real!=balance_end;blue:state=='draft' and (balance_end_real==balance_end);black:state in ('open')" string="Statement">
|
||||
<tree colors="red:balance_end_real!=balance_end;blue:state=='draft' and (balance_end_real==balance_end);black:state == 'open'" string="Statement">
|
||||
<field name="name"/>
|
||||
<field name="date"/>
|
||||
<field name="period_id"/>
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-08-25 17:24+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2011-09-13 09:07+0000\n"
|
||||
"Last-Translator: John Bradshaw <Unknown>\n"
|
||||
"Language-Team: English (United Kingdom) <en_GB@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: 2011-09-05 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 13830)\n"
|
||||
"X-Launchpad-Export-Date: 2011-09-14 04:40+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: account
|
||||
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
|
||||
|
@ -31,7 +31,7 @@ msgstr "Other Configuration"
|
|||
#: code:addons/account/wizard/account_open_closed_fiscalyear.py:40
|
||||
#, python-format
|
||||
msgid "No End of year journal defined for the fiscal year"
|
||||
msgstr ""
|
||||
msgstr "No End of year journal defined for the fiscal year"
|
||||
|
||||
#. module: account
|
||||
#: code:addons/account/account.py:516
|
||||
|
@ -318,7 +318,7 @@ msgstr "Allow write off"
|
|||
#. module: account
|
||||
#: view:account.analytic.chart:0
|
||||
msgid "Select the Period for Analysis"
|
||||
msgstr ""
|
||||
msgstr "Select the Period for Analysis"
|
||||
|
||||
#. module: account
|
||||
#: view:account.move.line:0
|
||||
|
@ -695,19 +695,19 @@ msgstr "Account Common Partner Report"
|
|||
#. module: account
|
||||
#: field:account.fiscalyear.close,period_id:0
|
||||
msgid "Opening Entries Period"
|
||||
msgstr ""
|
||||
msgstr "Opening Entries Period"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:account.model_account_journal_period
|
||||
msgid "Journal Period"
|
||||
msgstr ""
|
||||
msgstr "Journal Period"
|
||||
|
||||
#. module: account
|
||||
#: code:addons/account/account_move_line.py:723
|
||||
#: code:addons/account/account_move_line.py:767
|
||||
#, python-format
|
||||
msgid "To reconcile the entries company should be the same for all entries"
|
||||
msgstr ""
|
||||
msgstr "To reconcile the entries company should be the same for all entries"
|
||||
|
||||
#. module: account
|
||||
#: view:account.account:0
|
||||
|
@ -719,56 +719,56 @@ msgstr ""
|
|||
#: model:ir.actions.act_window,name:account.action_aged_receivable
|
||||
#, python-format
|
||||
msgid "Receivable Accounts"
|
||||
msgstr ""
|
||||
msgstr "Accounts Receivable"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:account.model_account_report_general_ledger
|
||||
msgid "General Ledger Report"
|
||||
msgstr ""
|
||||
msgstr "General Ledger Report"
|
||||
|
||||
#. module: account
|
||||
#: view:account.invoice:0
|
||||
msgid "Re-Open"
|
||||
msgstr ""
|
||||
msgstr "Re-Open"
|
||||
|
||||
#. module: account
|
||||
#: view:account.use.model:0
|
||||
msgid "Are you sure you want to create entries?"
|
||||
msgstr ""
|
||||
msgstr "Are you sure you want to create entries?"
|
||||
|
||||
#. module: account
|
||||
#: selection:account.bank.accounts.wizard,account_type:0
|
||||
msgid "Check"
|
||||
msgstr ""
|
||||
msgstr "Check"
|
||||
|
||||
#. module: account
|
||||
#: field:account.partner.reconcile.process,today_reconciled:0
|
||||
msgid "Partners Reconciled Today"
|
||||
msgstr ""
|
||||
msgstr "Partners Reconciled Today"
|
||||
|
||||
#. module: account
|
||||
#: selection:account.payment.term.line,value:0
|
||||
#: selection:account.tax.template,type:0
|
||||
msgid "Percent"
|
||||
msgstr ""
|
||||
msgstr "Percent"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.ui.menu,name:account.menu_finance_charts
|
||||
msgid "Charts"
|
||||
msgstr ""
|
||||
msgstr "Charts"
|
||||
|
||||
#. module: account
|
||||
#: code:addons/account/project/wizard/project_account_analytic_line.py:47
|
||||
#: model:ir.model,name:account.model_project_account_analytic_line
|
||||
#, python-format
|
||||
msgid "Analytic Entries by line"
|
||||
msgstr ""
|
||||
msgstr "Analytic Entries by line"
|
||||
|
||||
#. module: account
|
||||
#: code:addons/account/wizard/account_change_currency.py:38
|
||||
#, python-format
|
||||
msgid "You can only change currency for Draft Invoice !"
|
||||
msgstr ""
|
||||
msgstr "You can only change currency for Draft Invoice !"
|
||||
|
||||
#. module: account
|
||||
#: view:account.analytic.journal:0
|
||||
|
@ -782,17 +782,17 @@ msgstr ""
|
|||
#: field:account.move.reconcile,type:0
|
||||
#: field:report.invoice.created,type:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
msgstr "Type"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:account.model_account_subscription_line
|
||||
msgid "Account Subscription Line"
|
||||
msgstr ""
|
||||
msgstr "Account Subscription Line"
|
||||
|
||||
#. module: account
|
||||
#: help:account.invoice,reference:0
|
||||
msgid "The partner reference of this invoice."
|
||||
msgstr ""
|
||||
msgstr "The partner reference of this invoice."
|
||||
|
||||
#. module: account
|
||||
#: view:account.move.line.unreconcile.select:0
|
||||
|
@ -800,12 +800,12 @@ msgstr ""
|
|||
#: view:account.unreconcile.reconcile:0
|
||||
#: model:ir.model,name:account.model_account_move_line_unreconcile_select
|
||||
msgid "Unreconciliation"
|
||||
msgstr ""
|
||||
msgstr "Unreconciliation"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:account.model_account_analytic_Journal_report
|
||||
msgid "Account Analytic Journal"
|
||||
msgstr ""
|
||||
msgstr "Account Analytic Journal"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:account.model_account_automatic_reconcile
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_complete_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:type in ('view');red:(date<current_date);black:(date>=current_date);black:(date==False)" string="Analytic account" toolbar="1">
|
||||
<tree colors="blue:type == 'view';red:(date<current_date);black:(date>=current_date);black:(date==False)" string="Analytic account" toolbar="1">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="quantity"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.entries.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:move_state in ('draft');black:move_state in ('posted')" string="Entries Analysis">
|
||||
<tree colors="blue:move_state == 'draft';black:move_state == 'posted'" string="Entries Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="date_created" invisible="1"/>
|
||||
<field name="date_maturity" invisible="1"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.invoice.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Invoices Analysis">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Invoices Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<field name="model">report.invoice.created</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in('paid','cancel') " string="Invoices">
|
||||
<tree colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state in('paid','cancel') " string="Invoices">
|
||||
<field name="create_date" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="type"/>
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
# Macedonian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-14 08:10+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Macedonian <mk@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: 2011-09-15 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_qtt_invoiced:0
|
||||
msgid ""
|
||||
"Number of hours that can be invoiced plus those that already have been "
|
||||
"invoiced."
|
||||
msgstr ""
|
||||
"Број на часови кои можат да бидат фактурирани, плус часови кои веќе се "
|
||||
"фактурирани."
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,remaining_ca:0
|
||||
msgid "Computed using the formula: Max Invoice Price - Invoiced Amount."
|
||||
msgstr ""
|
||||
"Пресметано според формулата: Максимална фактурирана цена - Фактурирана цена."
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,remaining_hours:0
|
||||
msgid "Computed using the formula: Maximum Quantity - Hours Tot."
|
||||
msgstr "Пресметано според формулата: Максимална количина - Вкупно часови"
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: code:addons/account_analytic_analysis/account_analytic_analysis.py:532
|
||||
#: code:addons/account_analytic_analysis/account_analytic_analysis.py:703
|
||||
#, python-format
|
||||
msgid "AccessError"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,last_invoice_date:0
|
||||
msgid "Date of the last invoice created for this analytic account."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.module.module,description:account_analytic_analysis.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
"This module is for modifying account analytic view to show\n"
|
||||
"important data to project manager of services companies.\n"
|
||||
"Adds menu to show relevant information to each manager..\n"
|
||||
"\n"
|
||||
"You can also view the report of account analytic summary\n"
|
||||
"user-wise as well as month wise.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,last_invoice_date:0
|
||||
msgid "Last Invoice Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,theorical_margin:0
|
||||
msgid "Computed using the formula: Theorial Revenue - Total Costs"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,real_margin_rate:0
|
||||
msgid "Real Margin Rate (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,ca_theorical:0
|
||||
msgid "Theoretical Revenue"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,last_worked_invoiced_date:0
|
||||
msgid ""
|
||||
"If invoice from the costs, this is the date of the latest work or cost that "
|
||||
"have been invoiced."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.ui.menu,name:account_analytic_analysis.menu_invoicing
|
||||
msgid "Billing"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,last_worked_date:0
|
||||
msgid "Date of Last Cost/Work"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,total_cost:0
|
||||
msgid "Total Costs"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_quantity:0
|
||||
msgid ""
|
||||
"Number of hours you spent on the analytic account (from timesheet). It "
|
||||
"computes on all journal of type 'general'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,remaining_hours:0
|
||||
msgid "Remaining Hours"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,theorical_margin:0
|
||||
msgid "Theoretical Margin"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,ca_theorical:0
|
||||
msgid ""
|
||||
"Based on the costs you had on the project, what would have been the revenue "
|
||||
"if all these costs have been invoiced at the normal sale price provided by "
|
||||
"the pricelist."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,user_ids:0
|
||||
#: field:account_analytic_analysis.summary.user,user:0
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,ca_to_invoice:0
|
||||
msgid "Uninvoiced Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,real_margin:0
|
||||
msgid "Computed using the formula: Invoiced Amount - Total Costs."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,hours_qtt_non_invoiced:0
|
||||
msgid "Uninvoiced Hours"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,last_worked_date:0
|
||||
msgid "Date of the latest work done on this account."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.module.module,shortdesc:account_analytic_analysis.module_meta_information
|
||||
msgid "report_account_analytic"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.model,name:account_analytic_analysis.model_account_analytic_analysis_summary_user
|
||||
msgid "Hours Summary by User"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,ca_invoiced:0
|
||||
msgid "Invoiced Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: code:addons/account_analytic_analysis/account_analytic_analysis.py:533
|
||||
#: code:addons/account_analytic_analysis/account_analytic_analysis.py:704
|
||||
#, python-format
|
||||
msgid "You try to bypass an access rule (Document type: %s)."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,last_worked_invoiced_date:0
|
||||
msgid "Date of Last Invoiced Cost"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,hours_qtt_invoiced:0
|
||||
msgid "Invoiced Hours"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,real_margin:0
|
||||
msgid "Real Margin"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: constraint:account.analytic.account:0
|
||||
msgid ""
|
||||
"Error! The currency has to be the same as the currency of the selected "
|
||||
"company"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,ca_invoiced:0
|
||||
msgid "Total customer invoiced amount for this account."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.model,name:account_analytic_analysis.model_account_analytic_analysis_summary_month
|
||||
msgid "Hours summary by month"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,real_margin_rate:0
|
||||
msgid "Computes using the formula: (Real Margin / Total Costs) * 100."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_qtt_non_invoiced:0
|
||||
msgid ""
|
||||
"Number of hours (from journal of type 'general') that can be invoiced if you "
|
||||
"invoice based on analytic account."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: view:account.analytic.account:0
|
||||
msgid "Analytic accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,remaining_ca:0
|
||||
msgid "Remaining Revenue"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,ca_to_invoice:0
|
||||
msgid ""
|
||||
"If invoice from analytic account, the remaining amount you can invoice to "
|
||||
"the customer based on the total costs."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,revenue_per_hour:0
|
||||
msgid "Computed using the formula: Invoiced Amount / Hours Tot."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,revenue_per_hour:0
|
||||
msgid "Revenue per Hours (real)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account_analytic_analysis.summary.month,unit_amount:0
|
||||
#: field:account_analytic_analysis.summary.user,unit_amount:0
|
||||
msgid "Total Time"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,month_ids:0
|
||||
#: field:account_analytic_analysis.summary.month,month:0
|
||||
msgid "Month"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account_analytic_analysis.summary.month,account_id:0
|
||||
#: field:account_analytic_analysis.summary.user,account_id:0
|
||||
#: model:ir.model,name:account_analytic_analysis.model_account_analytic_account
|
||||
msgid "Analytic Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_managed_overpassed
|
||||
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_managed_overpassed
|
||||
msgid "Overpassed Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.actions.act_window,name:account_analytic_analysis.action_hr_tree_invoiced_all
|
||||
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_hr_tree_invoiced_all
|
||||
msgid "All Uninvoiced Entries"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: field:account.analytic.account,hours_quantity:0
|
||||
msgid "Hours Tot"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: constraint:account.analytic.account:0
|
||||
msgid "Error! You can not create recursive analytic accounts."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,total_cost:0
|
||||
msgid ""
|
||||
"Total of costs for this account. It includes real costs (from invoices) and "
|
||||
"indirect costs, like time spent on timesheets."
|
||||
msgstr ""
|
|
@ -152,7 +152,7 @@
|
|||
<field name="model">crossovered.budget</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done','cancel');black:state in ('confirm','validate')" string="Budget">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('done','cancel');black:state in ('confirm','validate')" string="Budget">
|
||||
<field name="name" colspan="1"/>
|
||||
<field name="code" colspan="1"/>
|
||||
<field name="date_from"/>
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
# Latvian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-12 13:54+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Latvian <lv@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: 2011-09-13 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13910)\n"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,journal_id:0
|
||||
#: field:account.coda.import,journal_id:0
|
||||
msgid "Bank Journal"
|
||||
msgstr "Banku žurnāls"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda.import,note:0
|
||||
msgid "Log"
|
||||
msgstr "Reģistrs"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_coda_import
|
||||
msgid "Account Coda Import"
|
||||
msgstr "Konta Pārskata Imports"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,name:0
|
||||
msgid "Coda file"
|
||||
msgstr "Pārskata fails"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Group By..."
|
||||
msgstr "Grupēt pēc..."
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,awaiting_account:0
|
||||
msgid "Default Account for Unrecognized Movement"
|
||||
msgstr "Noklusētais Konts Neatpazītām Kustībām"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,date:0
|
||||
msgid "Import Date"
|
||||
msgstr "Importa Datums"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,note:0
|
||||
msgid "Import log"
|
||||
msgstr "Importa žurnāls"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Import"
|
||||
msgstr "Importēt"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Coda import"
|
||||
msgstr "Pārskata Imports"
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/account_coda.py:51
|
||||
#, python-format
|
||||
msgid "Coda file not found for bank statement !!"
|
||||
msgstr "Bankas konta pārskata fails nav atrasts!"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,awaiting_account:0
|
||||
msgid ""
|
||||
"Set here the default account that will be used, if the partner is found but "
|
||||
"does not have the bank account, or if he is domiciled"
|
||||
msgstr ""
|
||||
"Iestatiet noklusējuma kontu, kas tiks izmantots, ja partneris ir atrasts, "
|
||||
"bet tam nav bankas konta vai adreses"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,company_id:0
|
||||
msgid "Company"
|
||||
msgstr "Uzņēmums"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,def_payable:0
|
||||
msgid ""
|
||||
"Set here the payable account that will be used, by default, if the partner "
|
||||
"is not found"
|
||||
msgstr ""
|
||||
"Uzstatiet kontu maksājumiem, kas tiks izmantots pēc noklusējuma, ja "
|
||||
"partneris nav atrasts"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Search Coda"
|
||||
msgstr "Meklēt Pārskatā"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,user_id:0
|
||||
msgid "User"
|
||||
msgstr "Lietotājs"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,date:0
|
||||
msgid "Date"
|
||||
msgstr "Datums"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.ui.menu,name:account_coda.menu_account_coda_statement
|
||||
msgid "Coda Import Logs"
|
||||
msgstr "Pārskata Importa Žurnāls"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_coda
|
||||
msgid "coda for an Account"
|
||||
msgstr "Konta Pārskats"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,def_payable:0
|
||||
msgid "Default Payable Account"
|
||||
msgstr "Noklusētais Maksājumu Konts"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,name:0
|
||||
msgid "Store the detail of bank statements"
|
||||
msgstr "Saglabāt bankas pārskata detaļas"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Cancel"
|
||||
msgstr "Atcelt"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Open Statements"
|
||||
msgstr "Atvērtie Pārskati"
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/wizard/account_coda_import.py:167
|
||||
#, python-format
|
||||
msgid "The bank account %s is not defined for the partner %s.\n"
|
||||
msgstr "Bankas konts %s partnerim %s nav definēts.\n"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.ui.menu,name:account_coda.menu_account_coda_import
|
||||
msgid "Import Coda Statements"
|
||||
msgstr "Importēt Bankas Pārskatus"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
#: model:ir.actions.act_window,name:account_coda.action_account_coda_import
|
||||
msgid "Import Coda Statement"
|
||||
msgstr "Importēt Bankas Pārskatu"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.module.module,description:account_coda.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
" Module provides functionality to import\n"
|
||||
" bank statements from coda files.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Modulis nodrošina iespēju importēt\n"
|
||||
" banku pārskatus no coda failiem.\n"
|
||||
" "
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Statements"
|
||||
msgstr "Izraksti"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.bank.statement,coda_id:0
|
||||
msgid "Coda"
|
||||
msgstr "Coda"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Results :"
|
||||
msgstr "Rezultāti:"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Result of Imported Coda Statements"
|
||||
msgstr "Importēto Pārskatu Rezultāti"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,def_receivable:0
|
||||
msgid ""
|
||||
"Set here the receivable account that will be used, by default, if the "
|
||||
"partner is not found"
|
||||
msgstr ""
|
||||
"Uzstatiet kontu ieņēmumiem, kas tiks izmantots pēc noklusējuma, ja partneris "
|
||||
"nav atrasts"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,coda:0
|
||||
#: model:ir.actions.act_window,name:account_coda.act_account_payment_account_bank_statement
|
||||
msgid "Coda File"
|
||||
msgstr "Coda Fails"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_bank_statement
|
||||
msgid "Bank Statement"
|
||||
msgstr "Bankas Konta Izraksts"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.actions.act_window,name:account_coda.action_account_coda
|
||||
msgid "Coda Logs"
|
||||
msgstr "Coda Žurnāls"
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/wizard/account_coda_import.py:311
|
||||
#, python-format
|
||||
msgid "Result"
|
||||
msgstr "Rezultāts"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Click on 'New' to select your file :"
|
||||
msgstr "Uzspiest uz 'Jauns' lai izvēlētos savu failu:"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,def_receivable:0
|
||||
msgid "Default Receivable Account"
|
||||
msgstr "Noklusētais Ieņēmumu Konts"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Close"
|
||||
msgstr "Aizvērt"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,statement_ids:0
|
||||
msgid "Generated Bank Statements"
|
||||
msgstr "Ģenerētais Bankas Pārskats"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.module.module,shortdesc:account_coda.module_meta_information
|
||||
msgid "Account CODA - import bank statements from coda file"
|
||||
msgstr "Konta CODA - bankas kontu pārskatu imports no coda faila"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Configure Your Journal and Account :"
|
||||
msgstr "Konfigurēt Savu Žurnālu un Kontu:"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Coda Import"
|
||||
msgstr "Pārskata Imports"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,journal_id:0
|
||||
msgid "Journal"
|
||||
msgstr "Žurnāls"
|
|
@ -0,0 +1,259 @@
|
|||
# Slovenian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-14 11:29+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Slovenian <sl@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: 2011-09-15 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,journal_id:0
|
||||
#: field:account.coda.import,journal_id:0
|
||||
msgid "Bank Journal"
|
||||
msgstr "Bančni dnevnik"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda.import,note:0
|
||||
msgid "Log"
|
||||
msgstr "Dnevnik"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_coda_import
|
||||
msgid "Account Coda Import"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,name:0
|
||||
msgid "Coda file"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Group By..."
|
||||
msgstr "Združi po ..."
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,awaiting_account:0
|
||||
msgid "Default Account for Unrecognized Movement"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,date:0
|
||||
msgid "Import Date"
|
||||
msgstr "Datum uvoza"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,note:0
|
||||
msgid "Import log"
|
||||
msgstr "Dnevnik uvoza"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Import"
|
||||
msgstr "Uvozi"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Coda import"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/account_coda.py:51
|
||||
#, python-format
|
||||
msgid "Coda file not found for bank statement !!"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,awaiting_account:0
|
||||
msgid ""
|
||||
"Set here the default account that will be used, if the partner is found but "
|
||||
"does not have the bank account, or if he is domiciled"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,company_id:0
|
||||
msgid "Company"
|
||||
msgstr "Podjetje"
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,def_payable:0
|
||||
msgid ""
|
||||
"Set here the payable account that will be used, by default, if the partner "
|
||||
"is not found"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Search Coda"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,user_id:0
|
||||
msgid "User"
|
||||
msgstr "Uporabnik"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,date:0
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.ui.menu,name:account_coda.menu_account_coda_statement
|
||||
msgid "Coda Import Logs"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_coda
|
||||
msgid "coda for an Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,def_payable:0
|
||||
msgid "Default Payable Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda,name:0
|
||||
msgid "Store the detail of bank statements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Cancel"
|
||||
msgstr "Prekliči"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Open Statements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/wizard/account_coda_import.py:167
|
||||
#, python-format
|
||||
msgid "The bank account %s is not defined for the partner %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.ui.menu,name:account_coda.menu_account_coda_import
|
||||
msgid "Import Coda Statements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
#: model:ir.actions.act_window,name:account_coda.action_account_coda_import
|
||||
msgid "Import Coda Statement"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.module.module,description:account_coda.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
" Module provides functionality to import\n"
|
||||
" bank statements from coda files.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Statements"
|
||||
msgstr "Izpiski"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.bank.statement,coda_id:0
|
||||
msgid "Coda"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Results :"
|
||||
msgstr "Rezultat"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Result of Imported Coda Statements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: help:account.coda.import,def_receivable:0
|
||||
msgid ""
|
||||
"Set here the receivable account that will be used, by default, if the "
|
||||
"partner is not found"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,coda:0
|
||||
#: model:ir.actions.act_window,name:account_coda.act_account_payment_account_bank_statement
|
||||
msgid "Coda File"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.model,name:account_coda.model_account_bank_statement
|
||||
msgid "Bank Statement"
|
||||
msgstr "Bančni izpisek"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.actions.act_window,name:account_coda.action_account_coda
|
||||
msgid "Coda Logs"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: code:addons/account_coda/wizard/account_coda_import.py:311
|
||||
#, python-format
|
||||
msgid "Result"
|
||||
msgstr "Rezultat"
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Click on 'New' to select your file :"
|
||||
msgstr "Kliknite na \"Novo\" za izbiro vaše datoteke:"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda.import,def_receivable:0
|
||||
msgid "Default Receivable Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Close"
|
||||
msgstr "Zapri"
|
||||
|
||||
#. module: account_coda
|
||||
#: field:account.coda,statement_ids:0
|
||||
msgid "Generated Bank Statements"
|
||||
msgstr "Generirani bačni izpiski"
|
||||
|
||||
#. module: account_coda
|
||||
#: model:ir.module.module,shortdesc:account_coda.module_meta_information
|
||||
msgid "Account CODA - import bank statements from coda file"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda.import:0
|
||||
msgid "Configure Your Journal and Account :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
msgid "Coda Import"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_coda
|
||||
#: view:account.coda:0
|
||||
#: field:account.coda,journal_id:0
|
||||
msgid "Journal"
|
||||
msgstr "Dnevnik"
|
|
@ -45,7 +45,7 @@ Note that if you want to check the followup level for a given partner/account en
|
|||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'images': ['images/follow_ups.jpeg','images/send_followups.jpeg'],
|
||||
'depends': ['account'],
|
||||
'depends': ['account_accountant', 'mail'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
'security/ir.model.access.csv',
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
<field name="description">
|
||||
Dear %(partner_name)s,
|
||||
|
||||
Exception made if there was a mistake of ours, it seems that the following amount staid unpaid. Please, take appropriate measures in order to carry out this payment in the next 8 days.
|
||||
Exception made if there was a mistake of ours, it seems that the following amount stays unpaid. Please, take appropriate measures in order to carry out this payment in the next 8 days.
|
||||
|
||||
Would your payment have been carried out after this mail was sent, please consider the present one as void. Do not hesitate to contact our accounting department at (+32).10.68.94.39.
|
||||
Would your payment have been carried out after this mail was sent, please ignore this message. Do not hesitate to contact our accounting department at (+32).10.68.94.39.
|
||||
|
||||
Best Regards,
|
||||
</field>
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="32" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:state in ('draft');black:state in ('validate')" editable="bottom" string="Partner entries">
|
||||
<tree colors="red:state == 'draft';black:state == 'validate'" editable="bottom" string="Partner entries">
|
||||
<field name="date"/>
|
||||
<field name="move_id"/>
|
||||
<field name="ref"/>
|
||||
|
|
|
@ -205,6 +205,7 @@ class account_followup_print_all(osv.osv_memory):
|
|||
move_obj = self.pool.get('account.move.line')
|
||||
user_obj = self.pool.get('res.users')
|
||||
line_obj = self.pool.get('account_followup.stat')
|
||||
mail_message = self.pool.get('mail.message')
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -277,7 +278,7 @@ class account_followup_print_all(osv.osv_memory):
|
|||
msg = ''
|
||||
if dest:
|
||||
try:
|
||||
tools.email_send(src, dest, sub, body)
|
||||
mail_message.schedule_with_attach(cr, uid, src, dest, sub, body, context=context)
|
||||
msg_sent += partner.name + '\n'
|
||||
except Exception, e:
|
||||
raise osv.except_osv('Error !', e )
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
# Danish translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-12 17:17+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Danish <da@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: 2011-09-13 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13910)\n"
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
msgid "Sub Total"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Note:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Cancelled Invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
#: field:notify.message,name:0
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.actions.act_window,name:account_invoice_layout.action_account_invoice_special_msg
|
||||
#: model:ir.actions.report.xml,name:account_invoice_layout.account_invoices_layout_message
|
||||
msgid "Invoices with Layout and Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Disc. (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.model,name:account_invoice_layout.model_notify_message
|
||||
msgid "Notify By Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: help:notify.message,msg:0
|
||||
msgid ""
|
||||
"This notification will appear at the bottom of the Invoices when printed."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Unit Price"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.module.module,description:account_invoice_layout.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
" This module provides some features to improve the layout of the "
|
||||
"invoices.\n"
|
||||
"\n"
|
||||
" It gives you the possibility to\n"
|
||||
" * order all the lines of an invoice\n"
|
||||
" * add titles, comment lines, sub total lines\n"
|
||||
" * draw horizontal lines and put page breaks\n"
|
||||
"\n"
|
||||
" Moreover, there is one option which allows you to print all the selected "
|
||||
"invoices with a given special message at the bottom of it. This feature can "
|
||||
"be very useful for printing your invoices with end-of-year wishes, special "
|
||||
"punctual conditions...\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "VAT :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Tel. :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "PRO-FORMA"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: field:account.invoice,abstract_line_ids:0
|
||||
msgid "Invoice Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:account.invoice.line:0
|
||||
msgid "Seq."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.ui.menu,name:account_invoice_layout.menu_finan_config_notify_message
|
||||
msgid "Notification Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: help:account.invoice.line,sequence:0
|
||||
msgid "Gives the sequence order when displaying a list of invoice lines."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Price"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Invoice Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
msgid "Taxes:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: field:account.invoice.line,functional_field:0
|
||||
msgid "Source Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.actions.act_window,name:account_invoice_layout.notify_mesage_tree_form
|
||||
msgid "Write Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Base"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
msgid "Page Break"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:notify.message:0
|
||||
#: field:notify.message,msg:0
|
||||
msgid "Special Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: help:account.invoice.special.msg,message:0
|
||||
msgid "Message to Print at the bottom of report"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Refund"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Fax :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
msgid "Total:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:account.invoice.special.msg:0
|
||||
msgid "Select Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:notify.message:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.actions.report.xml,name:account_invoice_layout.account_invoices_1
|
||||
msgid "Invoices with Layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Description / Taxes"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:notify.message,msg:account_invoice_layout.demo_message1
|
||||
msgid "ERP & CRM Solutions..."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Net Total :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Total :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Draft Invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: field:account.invoice.line,sequence:0
|
||||
msgid "Sequence Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.model,name:account_invoice_layout.model_account_invoice_special_msg
|
||||
msgid "Account Invoice Special Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Origin"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: field:account.invoice.line,state:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: selection:account.invoice.line,state:0
|
||||
msgid "Separator Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Your Reference"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.module.module,shortdesc:account_invoice_layout.module_meta_information
|
||||
msgid "Invoices Layout Improvement"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Supplier Invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:account.invoice.special.msg:0
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Tax"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.model,name:account_invoice_layout.model_account_invoice_line
|
||||
msgid "Invoice Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
msgid "Net Total:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:notify.message:0
|
||||
msgid "Write a notification or a wishful message."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: model:ir.model,name:account_invoice_layout.model_account_invoice
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: view:account.invoice.special.msg:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:account.invoice.layout:0
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Supplier Refund"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: field:account.invoice.special.msg,message:0
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: report:notify_account.invoice:0
|
||||
msgid "Taxes :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_invoice_layout
|
||||
#: model:ir.ui.menu,name:account_invoice_layout.menu_notify_mesage_tree_form
|
||||
msgid "All Notification Messages"
|
||||
msgstr ""
|
|
@ -179,7 +179,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','done');black:state == 'open'" string="Payment order">
|
||||
<field name="reference"/>
|
||||
<field name="mode"/>
|
||||
<field name="user_id"/>
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
# Latvian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-12 20:40+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Latvian <lv@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: 2011-09-13 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13910)\n"
|
||||
|
||||
#. module: account_sequence
|
||||
#: view:account.sequence.installer:0
|
||||
#: model:ir.actions.act_window,name:account_sequence.action_account_seq_installer
|
||||
msgid "Account Sequence Application Configuration"
|
||||
msgstr "Kontu Secības Aplikācijas Iestatījumi"
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move:0
|
||||
msgid ""
|
||||
"You cannot create entries on different periods/journals in the same move"
|
||||
msgstr "Jūs vienlaicīgi nevarat izveidot ierakstus dažādos periodos/žurnālos"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.move,internal_sequence_number:0
|
||||
#: help:account.move.line,internal_sequence_number:0
|
||||
msgid "Internal Sequence Number"
|
||||
msgstr "Iekšējais kārtas numurs"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.sequence.installer,number_next:0
|
||||
msgid "Next number of this sequence"
|
||||
msgstr "Šīs secības nākamais numurs"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,number_next:0
|
||||
msgid "Next Number"
|
||||
msgstr "Nākamais Numurs"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,number_increment:0
|
||||
msgid "Increment Number"
|
||||
msgstr "Soļa Numurs"
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.module.module,description:account_sequence.module_meta_information
|
||||
msgid ""
|
||||
"\n"
|
||||
" This module maintains internal sequence number for accounting entries.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Šis modulis nodrošina iekšējo kārtas numuru grāmatošanas ierakstiem.\n"
|
||||
" "
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.module.module,shortdesc:account_sequence.module_meta_information
|
||||
msgid "Entries Sequence Numbering"
|
||||
msgstr "Ierakstu Kārtas Numerācija"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.sequence.installer,number_increment:0
|
||||
msgid "The next number of the sequence will be incremented by this number"
|
||||
msgstr "Sekvences nākamais numurs tiks palielināts par šo skaitli"
|
||||
|
||||
#. module: account_sequence
|
||||
#: view:account.sequence.installer:0
|
||||
msgid "Configure Your Account Sequence Application"
|
||||
msgstr "Konfigurēt Tavu Konta Sesības Aplikāciju"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,progress:0
|
||||
msgid "Configuration Progress"
|
||||
msgstr "Konfigurācijas Progress"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.sequence.installer,suffix:0
|
||||
msgid "Suffix value of the record for the sequence"
|
||||
msgstr "Sekvences ieraksta piedēkļa vērtiba"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,company_id:0
|
||||
msgid "Company"
|
||||
msgstr "Uzņēmums"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.journal,internal_sequence_id:0
|
||||
msgid ""
|
||||
"This sequence will be used to maintain the internal number for the journal "
|
||||
"entries related to this journal."
|
||||
msgstr ""
|
||||
"Šo secību izmantos, lai izveidotu ar šo žurnālu saistīto žurnāla ierakstu "
|
||||
"iekšējo numerāciju"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,padding:0
|
||||
msgid "Number padding"
|
||||
msgstr "Numerācijas garums"
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.model,name:account_sequence.model_account_move_line
|
||||
msgid "Journal Items"
|
||||
msgstr "Žurnāla Vienumi"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.move,internal_sequence_number:0
|
||||
#: field:account.move.line,internal_sequence_number:0
|
||||
msgid "Internal Number"
|
||||
msgstr "Iekšējā Numerācija"
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move.line:0
|
||||
msgid "Company must be same for its related account and period."
|
||||
msgstr "Uzņēmumam ir jāsakrīt ar saistīto kontu un periodu."
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.sequence.installer,padding:0
|
||||
msgid ""
|
||||
"OpenERP will automatically adds some '0' on the left of the 'Next Number' to "
|
||||
"get the required padding size."
|
||||
msgstr ""
|
||||
"OpenERP automātiski pievienos kādu '0' iedaļas 'Nākamais Numurs' kreisajā "
|
||||
"pusē lai iegūtu nepieciešamo numerācijas garumu."
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,name:0
|
||||
msgid "Name"
|
||||
msgstr "Nosaukums"
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move.line:0
|
||||
msgid "You can not create move line on closed account."
|
||||
msgstr "Nav iespējams veikt grāmatojumus slēgtā kontā."
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move:0
|
||||
msgid ""
|
||||
"You cannot create more than one move per period on centralized journal"
|
||||
msgstr ""
|
||||
"Jūs nevarat centralizētā žurnālā izveidot vairāk par vienu pārvietošanu "
|
||||
"vienā periodā"
|
||||
|
||||
#. module: account_sequence
|
||||
#: sql_constraint:account.move.line:0
|
||||
msgid "Wrong credit or debit value in accounting entry !"
|
||||
msgstr "Kļūdaina kredīta vai debeta vērtība grāmatojumā!"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.journal,internal_sequence_id:0
|
||||
msgid "Internal Sequence"
|
||||
msgstr "Iekšējā Sekvence"
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.model,name:account_sequence.model_account_sequence_installer
|
||||
msgid "account.sequence.installer"
|
||||
msgstr "account.sequence.installer"
|
||||
|
||||
#. module: account_sequence
|
||||
#: view:account.sequence.installer:0
|
||||
msgid "Configure"
|
||||
msgstr "Konfigurēt"
|
||||
|
||||
#. module: account_sequence
|
||||
#: help:account.sequence.installer,prefix:0
|
||||
msgid "Prefix value of the record for the sequence"
|
||||
msgstr "Piedēkļa vērtība sekvences ierakstiem"
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.model,name:account_sequence.model_account_move
|
||||
msgid "Account Entry"
|
||||
msgstr "Kontējums"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,suffix:0
|
||||
msgid "Suffix"
|
||||
msgstr "Priedēklis"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,config_logo:0
|
||||
msgid "Image"
|
||||
msgstr "Attēls"
|
||||
|
||||
#. module: account_sequence
|
||||
#: view:account.sequence.installer:0
|
||||
msgid "title"
|
||||
msgstr "nosaukums"
|
||||
|
||||
#. module: account_sequence
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The name of the journal must be unique per company !"
|
||||
msgstr "Žurnāla nosaukumam katrai kompānijai ir jābūt unikālam!"
|
||||
|
||||
#. module: account_sequence
|
||||
#: field:account.sequence.installer,prefix:0
|
||||
msgid "Prefix"
|
||||
msgstr "Priedēklis"
|
||||
|
||||
#. module: account_sequence
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The code of the journal must be unique per company !"
|
||||
msgstr "Žurnāla kodam ir jābūt unikālam katram uzņēmumam!"
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move.line:0
|
||||
msgid ""
|
||||
"You can not create move line on receivable/payable account without partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_sequence
|
||||
#: model:ir.model,name:account_sequence.model_account_journal
|
||||
msgid "Journal"
|
||||
msgstr "Žurnāls"
|
||||
|
||||
#. module: account_sequence
|
||||
#: view:account.sequence.installer:0
|
||||
msgid "You can enhance the Account Sequence Application by installing ."
|
||||
msgstr "Ar šo moduli jūs varat uzlabot Konta Sekvences Aplikāciju."
|
||||
|
||||
#. module: account_sequence
|
||||
#: constraint:account.move.line:0
|
||||
msgid "You can not create move line on view account."
|
||||
msgstr "Jūs nevarat izveidor grāmatojumu pārskata kontam."
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.voucher</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel');red:audit" string="Voucher Entries">
|
||||
<tree colors="blue:state == 'draft';gray:state == 'cancel';red:audit" string="Voucher Entries">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="reference"/>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<field name="model">sale.receipt.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Sales Receipt Analysis">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Sales Receipt Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
<separator string="Buyer Invoices" colspan="2"/>
|
||||
<field name="buyer_invoice_history" nolabel="1" widget="one2many_list"
|
||||
height="400">
|
||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in ('cancel')" string="Invoice">
|
||||
<tree colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'" string="Invoice">
|
||||
<field name="date_invoice"/>
|
||||
<field name="number"/>
|
||||
<field name="partner_id" groups="base.group_user"/>
|
||||
|
@ -177,7 +177,7 @@
|
|||
<separator string="Seller Invoices" colspan="2"/>
|
||||
<field name="seller_invoice_history" nolabel="1" widget="one2many_list"
|
||||
height="400">
|
||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in ('cancel')" string="Invoice">
|
||||
<tree colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'" string="Invoice">
|
||||
<field name="date_invoice"/>
|
||||
<field name="number"/>
|
||||
<field name="partner_id" groups="base.group_user"/>
|
||||
|
@ -272,7 +272,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="priority" eval="1"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('unsold','draft');black:state in ('sold','taken_away');gray:state in ('paid') " string="Objects">
|
||||
<tree colors="blue:state in ('unsold','draft');black:state in ('sold','taken_away');gray:state == 'paid' " string="Objects">
|
||||
<field name="obj_num" string="Ref" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="ach_uid"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<field name="model">audittrail.rule</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('subscribed')" string="AuditTrail Rules">
|
||||
<tree colors="blue:state == 'draft';black:state == 'subscribed'" string="AuditTrail Rules">
|
||||
<field name="name" />
|
||||
<field name="object_id"/>
|
||||
<field name="log_read" />
|
||||
|
|
|
@ -37,7 +37,7 @@ trigger an automatic reminder email.
|
|||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'depends': ['base', 'mail'],
|
||||
'init_xml': [
|
||||
'base_action_rule_data.xml'
|
||||
],
|
||||
|
|
|
@ -24,7 +24,7 @@ from tools.translate import _
|
|||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
from tools.safe_eval import safe_eval
|
||||
import pooler
|
||||
import pooler
|
||||
import re
|
||||
import time
|
||||
import tools
|
||||
|
@ -39,7 +39,7 @@ class base_action_rule(osv.osv):
|
|||
|
||||
_name = 'base.action.rule'
|
||||
_description = 'Action Rules'
|
||||
|
||||
|
||||
def _state_get(self, cr, uid, context=None):
|
||||
""" Get State
|
||||
@param self: The object pointer
|
||||
|
@ -55,7 +55,7 @@ class base_action_rule(osv.osv):
|
|||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values """
|
||||
return [('', '')]
|
||||
|
||||
|
||||
def priority_get(self, cr, uid, context=None):
|
||||
""" Get Priority
|
||||
@param self: The object pointer
|
||||
|
@ -65,57 +65,57 @@ class base_action_rule(osv.osv):
|
|||
return [('', '')]
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Rule Name', size=64, required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Object', required=True),
|
||||
'create_date': fields.datetime('Create Date', readonly=1),
|
||||
'name': fields.char('Rule Name', size=64, required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Object', required=True),
|
||||
'create_date': fields.datetime('Create Date', readonly=1),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False,\
|
||||
it will allow you to hide the rule without removing it."),
|
||||
it will allow you to hide the rule without removing it."),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order \
|
||||
when displaying a list of rules."),
|
||||
when displaying a list of rules."),
|
||||
'trg_date_type': fields.selection([
|
||||
('none', 'None'),
|
||||
('create', 'Creation Date'),
|
||||
('action_last', 'Last Action Date'),
|
||||
('date', 'Date'),
|
||||
('deadline', 'Deadline'),
|
||||
], 'Trigger Date', size=16),
|
||||
('none', 'None'),
|
||||
('create', 'Creation Date'),
|
||||
('action_last', 'Last Action Date'),
|
||||
('date', 'Date'),
|
||||
('deadline', 'Deadline'),
|
||||
], 'Trigger Date', size=16),
|
||||
'trg_date_range': fields.integer('Delay after trigger date', \
|
||||
help="Delay After Trigger Date,\
|
||||
specifies you can put a negative number. If you need a delay before the \
|
||||
trigger date, like sending a reminder 15 minutes before a meeting."),
|
||||
trigger date, like sending a reminder 15 minutes before a meeting."),
|
||||
'trg_date_range_type': fields.selection([('minutes', 'Minutes'), ('hour', 'Hours'), \
|
||||
('day', 'Days'), ('month', 'Months')], 'Delay type'),
|
||||
'trg_user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'trg_partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'),
|
||||
'trg_state_from': fields.selection(_state_get, 'State', size=16),
|
||||
'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
|
||||
('day', 'Days'), ('month', 'Months')], 'Delay type'),
|
||||
'trg_user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'trg_partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'),
|
||||
'trg_state_from': fields.selection(_state_get, 'State', size=16),
|
||||
'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
|
||||
|
||||
'act_method': fields.char('Call Object Method', size=64),
|
||||
'act_user_id': fields.many2one('res.users', 'Set Responsible to'),
|
||||
'act_state': fields.selection(_state_get, 'Set State to', size=16),
|
||||
'act_method': fields.char('Call Object Method', size=64),
|
||||
'act_user_id': fields.many2one('res.users', 'Set Responsible to'),
|
||||
'act_state': fields.selection(_state_get, 'Set State to', size=16),
|
||||
'act_email_cc': fields.char('Add Watchers (Cc)', size=250, help="\
|
||||
These people will receive a copy of the future communication between partner \
|
||||
and users by email"),
|
||||
and users by email"),
|
||||
'act_remind_partner': fields.boolean('Remind Partner', help="Check \
|
||||
this if you want the rule to send a reminder by email to the partner."),
|
||||
this if you want the rule to send a reminder by email to the partner."),
|
||||
'act_remind_user': fields.boolean('Remind Responsible', help="Check \
|
||||
this if you want the rule to send a reminder by email to the user."),
|
||||
'act_reply_to': fields.char('Reply-To', size=64),
|
||||
'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
|
||||
this if you want the rule to send a reminder by email to the user."),
|
||||
'act_reply_to': fields.char('Reply-To', size=64),
|
||||
'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
|
||||
'act_mail_to_user': fields.boolean('Mail to Responsible', help="Check\
|
||||
this if you want the rule to send an email to the responsible person."),
|
||||
'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)',
|
||||
this if you want the rule to send an email to the responsible person."),
|
||||
'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)',
|
||||
help="Check this if you want \
|
||||
the rule to mark CC(mail to any other person defined in actions)."),
|
||||
the rule to mark CC(mail to any other person defined in actions)."),
|
||||
'act_mail_to_email': fields.char('Mail to these Emails', size=128, \
|
||||
help="Email-id of the persons whom mail is to be sent"),
|
||||
'act_mail_body': fields.text('Mail body', help="Content of mail"),
|
||||
help="Email-id of the persons whom mail is to be sent"),
|
||||
'act_mail_body': fields.text('Mail body', help="Content of mail"),
|
||||
'regex_name': fields.char('Regex on Resource Name', size=128, help="Regular expression for matching name of the resource\
|
||||
\ne.g.: 'urgent.*' will search for records having name starting with the string 'urgent'\
|
||||
\nNote: This is case sensitive search."),
|
||||
'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"),
|
||||
'filter_id':fields.many2one('ir.filters', 'Filter', required=False),
|
||||
\nNote: This is case sensitive search."),
|
||||
'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"),
|
||||
'filter_id':fields.many2one('ir.filters', 'Filter', required=False),
|
||||
'act_email_from' : fields.char('Email From', size=64, required=False,
|
||||
help="Use a python expression to specify the right field on which one than we will use for the 'From' field of the header"),
|
||||
'act_email_to' : fields.char('Email To', size=64, required=False,
|
||||
|
@ -124,17 +124,17 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: True,
|
||||
'trg_date_type': lambda *a: 'none',
|
||||
'trg_date_range_type': lambda *a: 'day',
|
||||
'act_mail_to_user': lambda *a: 0,
|
||||
'act_remind_partner': lambda *a: 0,
|
||||
'act_remind_user': lambda *a: 0,
|
||||
'act_mail_to_watchers': lambda *a: 0,
|
||||
'active': lambda *a: True,
|
||||
'trg_date_type': lambda *a: 'none',
|
||||
'trg_date_range_type': lambda *a: 'day',
|
||||
'act_mail_to_user': lambda *a: 0,
|
||||
'act_remind_partner': lambda *a: 0,
|
||||
'act_remind_user': lambda *a: 0,
|
||||
'act_mail_to_watchers': lambda *a: 0,
|
||||
}
|
||||
|
||||
|
||||
_order = 'sequence'
|
||||
|
||||
|
||||
def onchange_model_id(self, cr, uid, ids, name):
|
||||
#This is not a good solution as it will affect the domain only on onchange
|
||||
res = {'domain':{'filter_id':[]}}
|
||||
|
@ -174,7 +174,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
self.pre_action(cr, uid, [new_id], model, context=context)
|
||||
return new_id
|
||||
return make_call_old
|
||||
|
||||
|
||||
def _write(self, old_write, model, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -202,9 +202,9 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
return True
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
res_id = super(base_action_rule, self).create(cr, uid, vals, context=context)
|
||||
self._register_hook(cr, uid, [res_id], context=context)
|
||||
self._register_hook(cr, uid, [res_id], context=context)
|
||||
return res_id
|
||||
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
res = super(base_action_rule, self).write(cr, uid, ids, vals, context=context)
|
||||
self._register_hook(cr, uid, ids, context=context)
|
||||
|
@ -268,22 +268,19 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
return body and tools.ustr(body) or ''
|
||||
|
||||
def format_mail(self, obj, body):
|
||||
""" Foramat Mail
|
||||
@param self: The object pointer """
|
||||
|
||||
data = {
|
||||
'object_id': obj.id,
|
||||
'object_subject': hasattr(obj, 'name') and obj.name or False,
|
||||
'object_date': hasattr(obj, 'date') and obj.date or False,
|
||||
'object_description': hasattr(obj, 'description') and obj.description or False,
|
||||
'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/',
|
||||
'object_id': obj.id,
|
||||
'object_subject': hasattr(obj, 'name') and obj.name or False,
|
||||
'object_date': hasattr(obj, 'date') and obj.date or False,
|
||||
'object_description': hasattr(obj, 'description') and obj.description or False,
|
||||
'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/',
|
||||
'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \
|
||||
obj.user_id.user_email) or '/',
|
||||
'object_user_phone': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and \
|
||||
obj.partner_address_id.phone) or '/',
|
||||
'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/',
|
||||
'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/',
|
||||
'partner_email': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and\
|
||||
obj.partner_address_id.email) or '/',
|
||||
obj.partner_address_id.email) or '/',
|
||||
}
|
||||
return self.format_body(body % data)
|
||||
|
||||
|
@ -302,6 +299,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
if context is None:
|
||||
context = {}
|
||||
|
||||
mail_message = self.pool.get('mail.message')
|
||||
body = self.format_mail(obj, body)
|
||||
if not emailfrom:
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.user_email:
|
||||
|
@ -311,9 +309,9 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
emailfrom = tools.ustr(emailfrom)
|
||||
reply_to = emailfrom
|
||||
if not emailfrom:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_("No E-Mail ID Found for your Company address!"))
|
||||
return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
|
||||
return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, res_id=obj.id)
|
||||
|
||||
|
||||
def do_check(self, cr, uid, action, obj, context=None):
|
||||
|
@ -324,7 +322,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
@param context: A standard dictionary for contextual values """
|
||||
if context is None:
|
||||
context = {}
|
||||
ok = True
|
||||
ok = True
|
||||
if action.filter_id:
|
||||
if action.model_id.model == action.filter_id.model_id:
|
||||
context.update(eval(action.filter_id.context))
|
||||
|
@ -479,7 +477,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
|
|||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_mail, 'Error: The mail is not well formated', ['act_mail_body']),
|
||||
(_check_mail, 'Error: The mail is not well formated', ['act_mail_body']),
|
||||
]
|
||||
|
||||
base_action_rule()
|
||||
|
|
|
@ -20,30 +20,37 @@
|
|||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Email Gateway System',
|
||||
'version': '1.0',
|
||||
'category': 'Tools',
|
||||
"name" : "Basic Calendar Functionality",
|
||||
"version" : "1.0",
|
||||
"depends" : ["base", "mail"],
|
||||
'complexity': "easy",
|
||||
'description': """
|
||||
The generic email gateway system allows to send and receive emails.
|
||||
===================================================================
|
||||
This is a full-featured calendar system.
|
||||
========================================
|
||||
|
||||
* History of emails
|
||||
* Easy integration with any module""",
|
||||
'author': 'OpenERP SA',
|
||||
It supports:
|
||||
- Calendar of events
|
||||
- Alerts (create requests)
|
||||
- Recurring events
|
||||
- Invitations to people""",
|
||||
"author" : "OpenERP SA",
|
||||
'category': 'Tools',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
"mail_gateway_view.xml",
|
||||
"res_partner_view.xml",
|
||||
'security/ir.model.access.csv'
|
||||
|
||||
"init_xml" : [
|
||||
'base_calendar_data.xml'
|
||||
],
|
||||
'demo_xml': [],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '001056784984222247309',
|
||||
'images': ['images/customer_history.jpeg','images/messages_form.jpeg','images/messages_list.jpeg'],
|
||||
"demo_xml" : [],
|
||||
"update_xml" : [
|
||||
'security/calendar_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/base_calendar_invite_attendee_view.xml',
|
||||
'base_calendar_view.xml'
|
||||
],
|
||||
"test" : ['test/base_calendar_test.yml'],
|
||||
"installable" : True,
|
||||
"active" : False,
|
||||
"certificate" : "00694071962960352821",
|
||||
'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',],
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -484,6 +484,7 @@ property or property parameter."),
|
|||
context = {}
|
||||
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
||||
mail_message = self.pool.get('mail.message')
|
||||
for att in self.browse(cr, uid, ids, context=context):
|
||||
sign = att.sent_by_uid and att.sent_by_uid.signature or ''
|
||||
sign = '<br>'.join(sign and sign.split('\n') or [])
|
||||
|
@ -510,14 +511,15 @@ property or property parameter."),
|
|||
body = html_invitation % body_vals
|
||||
if mail_to and email_from:
|
||||
attach = self.get_ics_file(cr, uid, res_obj, context=context)
|
||||
tools.email_send(
|
||||
mail_message.schedule_with_attach(cr, uid,
|
||||
email_from,
|
||||
mail_to,
|
||||
sub,
|
||||
body,
|
||||
attach=attach and [('invitation.ics', attach)] or None,
|
||||
attachments=attach and {'invitation.ics': attach} or None,
|
||||
subtype='html',
|
||||
reply_to=email_from
|
||||
reply_to=email_from,
|
||||
context=context
|
||||
)
|
||||
return True
|
||||
|
||||
|
@ -812,6 +814,7 @@ class calendar_alarm(osv.osv):
|
|||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
mail_message = self.pool.get('mail.message')
|
||||
current_datetime = datetime.now()
|
||||
request_obj = self.pool.get('res.request')
|
||||
alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context)
|
||||
|
@ -893,11 +896,12 @@ From:
|
|||
for att in alarm.attendee_ids:
|
||||
mail_to.append(att.user_id.user_email)
|
||||
if mail_to:
|
||||
tools.email_send(
|
||||
mail_message.schedule_with_attach(cr, uid,
|
||||
tools.config.get('email_from', False),
|
||||
mail_to,
|
||||
sub,
|
||||
body
|
||||
body,
|
||||
context=context
|
||||
)
|
||||
if next_trigger_date:
|
||||
update_vals.update({'trigger_date': next_trigger_date})
|
||||
|
@ -1038,7 +1042,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
||||
'organizer': fields.char("Organizer", size=256, states={'done': [('readonly', True)]}), # Map with Organizer Attribure of VEvent.
|
||||
'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}),
|
||||
'end_type' : fields.selection([('count', 'Fix amout of times'), ('end_date','End date')], 'Way to end reccurency'),
|
||||
'end_type' : fields.selection([('count', 'Number of repetitions'), ('end_date','End date')], 'Recurrence termination'),
|
||||
'interval': fields.integer('Repeat every', help="Repeat every (Days/Week/Month/Year)"),
|
||||
'count': fields.integer('Repeat', help="Repeat x times"),
|
||||
'mo': fields.boolean('Mon'),
|
||||
|
@ -1199,13 +1203,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
|
||||
return (datas.get('end_type') == 'count' and (';COUNT=' + str(datas.get('count'))) or '') +\
|
||||
((datas.get('end_date_new') and datas.get('end_type') == 'end_date' and (';UNTIL=' + datas.get('end_date_new'))) or '')
|
||||
|
||||
|
||||
freq=datas.get('rrule_type')
|
||||
if freq == 'none':
|
||||
return ''
|
||||
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
|
||||
return 'FREQ=' + freq.upper() + get_week_string(freq, datas) + interval_srting + get_end_date(datas) + get_month_string(freq, datas)
|
||||
|
||||
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
|
||||
|
||||
return 'FREQ=' + freq.upper() + get_week_string(freq, datas) + interval_srting + get_end_date(datas) + get_month_string(freq, datas)
|
||||
|
||||
def remove_virtual_id(self, ids):
|
||||
if isinstance(ids, (str, int)):
|
||||
|
@ -1216,9 +1221,8 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
for id in ids:
|
||||
res.append(base_calendar_id2real_id(id))
|
||||
return res
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=0, order=None,
|
||||
context=None, count=False):
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False):
|
||||
args_without_date = []
|
||||
start_date = False
|
||||
until_date = False
|
||||
|
@ -1250,7 +1254,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
else:
|
||||
return res
|
||||
|
||||
|
||||
def get_edit_all(self, cr, uid, id, vals=None):
|
||||
"""
|
||||
return true if we have to edit all meeting from the same recurrent
|
||||
|
@ -1277,7 +1280,8 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
return date_start == split_id[1]
|
||||
except Exception:
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -1289,7 +1293,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
res = False
|
||||
for event_id in select:
|
||||
real_event_id = base_calendar_id2real_id(event_id)
|
||||
|
||||
edit_all = self.get_edit_all(cr, uid, event_id, vals=vals)
|
||||
if edit_all:
|
||||
if self.need_to_update(event_id, vals):
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
# Slovenian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-09-14 11:36+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Slovenian <sl@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: 2011-09-15 04:48+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: base_crypt
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr "Ne morete imeti dva uporabnika z istim prijavnim imenom!"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.model,name:base_crypt.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr "res.users"
|
||||
|
||||
#. module: base_crypt
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr "Izbrano podjetje ni v dovoljenih podjetjih za tega uporabnika"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:132
|
||||
#, python-format
|
||||
msgid "Please specify the password !"
|
||||
msgstr "Prosim, navedite geslo !"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.module.module,shortdesc:base_crypt.module_meta_information
|
||||
msgid "Base - Password Encryption"
|
||||
msgstr "Osnovno - enkripcija gesla"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:132
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Napaka"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.module.module,description:base_crypt.module_meta_information
|
||||
msgid ""
|
||||
"This module replaces the cleartext password in the database with a password "
|
||||
"hash,\n"
|
||||
"preventing anyone from reading the original password.\n"
|
||||
"For your existing user base, the removal of the cleartext passwords occurs "
|
||||
"the first time\n"
|
||||
"a user logs into the database, after installing base_crypt.\n"
|
||||
"After installing this module it won't be possible to recover a forgotten "
|
||||
"password for your\n"
|
||||
"users, the only solution is for an admin to set a new password.\n"
|
||||
"\n"
|
||||
"Note: installing this module does not mean you can ignore basic security "
|
||||
"measures,\n"
|
||||
"as the password is still transmitted unencrypted on the network (by the "
|
||||
"client),\n"
|
||||
"unless you are using a secure protocol such as XML-RPCS.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ta modul nadomešča obliko besedilnega geslo v bazi podatkov z hash geslom,\n"
|
||||
"ki preprečuje komurkoli branje izvirnega gesla.\n"
|
||||
"Za vašo obstoječo bazo uporabnikov, odstranitev gesla v obliki besedila se "
|
||||
"pojavi pri\n"
|
||||
"prvi prijavi uporabnika v bazo podatkov, po namestitvi base_crypt.\n"
|
||||
"Po namestitvi tega modula ne bo mogoče obnoviti pozabiljenega gesla za vaše\n"
|
||||
"uporabnike, edina rešitev je, da admin nastavi novo geslo.\n"
|
||||
"\n"
|
||||
"Opomba: namestitev tega modula ne pomeni ignoriranja osnovnih varnostnih "
|
||||
"ukrepov,\n"
|
||||
"ker se geslo še vedno prenaša nešifrirano v omrežju (preko klienta),\n"
|
||||
"razen če ne uporabljate varni protokol kot je XML-RPCS.\n"
|
||||
" "
|
|
@ -4,27 +4,28 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2009-02-03 06:26+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"PO-Revision-Date: 2011-09-09 10:24+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"Language-Team: Czech <cs@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: 2011-09-05 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 13830)\n"
|
||||
"X-Launchpad-Export-Date: 2011-09-10 05:01+0000\n"
|
||||
"X-Generator: Launchpad (build 13900)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,category:0
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
msgstr "Kategorie"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,save:0
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
msgstr "Informace"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,save:0
|
||||
|
@ -33,54 +34,57 @@ msgid ""
|
|||
"publish it on OpenERP.com, in the 'Modules' section. You can do it through "
|
||||
"the website or using features of the 'base_module_publish' module."
|
||||
msgstr ""
|
||||
"Pokud si myslíte, že by váš modul mohl zajímat další lidi, byli bychom rádi, "
|
||||
"kdybyste jej zveřejnili na OpenERP.com v sekci 'Moduly'. Můžete to provést "
|
||||
"přes webové stránky nebo pomocí funkcí modulu 'base_module_publish'."
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_data,info,end:0
|
||||
#: wizard_button:base_module_record.module_record_data,save_yaml,end:0
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
msgstr "Ukončit"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_data,init:0
|
||||
#: wizard_view:base_module_record.module_record_objects,init:0
|
||||
msgid "Choose objects to record"
|
||||
msgstr ""
|
||||
msgstr "Vyberte objekt pro zaznamenání"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,author:0
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,directory_name:0
|
||||
msgid "Directory Name"
|
||||
msgstr ""
|
||||
msgstr "Jméno adresáře"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,init,filter_cond:0
|
||||
#: wizard_field:base_module_record.module_record_objects,init,filter_cond:0
|
||||
msgid "Records only"
|
||||
msgstr ""
|
||||
msgstr "Piouze záznam"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.model,name:base_module_record.model_ir_module_record
|
||||
msgid "ir.module.record"
|
||||
msgstr ""
|
||||
msgstr "ir.module.record"
|
||||
|
||||
#. module: base_module_record
|
||||
#: selection:base_module_record.module_record_objects,info,data_kind:0
|
||||
msgid "Demo Data"
|
||||
msgstr ""
|
||||
msgstr "Ukázková data"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,save,module_filename:0
|
||||
msgid "Filename"
|
||||
msgstr ""
|
||||
msgstr "Jméno souboru"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,version:0
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
msgstr "Verze"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_data,info:0
|
||||
|
@ -88,13 +92,13 @@ msgstr ""
|
|||
#: wizard_view:base_module_record.module_record_data,save_yaml:0
|
||||
#: wizard_view:base_module_record.module_record_objects,init:0
|
||||
msgid "Objects Recording"
|
||||
msgstr ""
|
||||
msgstr "Zaznamenávání objektů"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,init,check_date:0
|
||||
#: wizard_field:base_module_record.module_record_objects,init,check_date:0
|
||||
msgid "Record from Date"
|
||||
msgstr ""
|
||||
msgstr "Záznam od data"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_data,end:0
|
||||
|
@ -103,170 +107,170 @@ msgstr ""
|
|||
#: wizard_view:base_module_record.module_record_objects,save:0
|
||||
#: wizard_view:base_module_record.module_record_objects,save_yaml:0
|
||||
msgid "Module Recording"
|
||||
msgstr ""
|
||||
msgstr "Zaznamenávání modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.actions.wizard,name:base_module_record.wizard_base_module_record_objects
|
||||
#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_module_record_objects
|
||||
msgid "Export Customizations As a Module"
|
||||
msgstr ""
|
||||
msgstr "Exportovat vlastní úpravy jako modul"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,save:0
|
||||
msgid "Thanks in advance for your contribution."
|
||||
msgstr ""
|
||||
msgstr "Předem díky za váše přispění."
|
||||
|
||||
#. module: base_module_record
|
||||
#: help:base_module_record.module_record_data,init,objects:0
|
||||
#: help:base_module_record.module_record_objects,init,objects:0
|
||||
msgid "List of objects to be recorded"
|
||||
msgstr ""
|
||||
msgstr "Seznam objektů k záznamu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,description:0
|
||||
msgid "Full Description"
|
||||
msgstr ""
|
||||
msgstr "Plný popis"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,name:0
|
||||
msgid "Module Name"
|
||||
msgstr ""
|
||||
msgstr "Jméno modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,init,objects:0
|
||||
#: wizard_field:base_module_record.module_record_objects,init,objects:0
|
||||
msgid "Objects"
|
||||
msgstr ""
|
||||
msgstr "Objekty"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,save,module_file:0
|
||||
#: wizard_field:base_module_record.module_record_objects,save_yaml,yaml_file:0
|
||||
msgid "Module .zip File"
|
||||
msgstr ""
|
||||
msgstr ".ZIP soubor modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,save:0
|
||||
msgid "Module successfully created !"
|
||||
msgstr ""
|
||||
msgstr "Modul úspěšně vytvořen !"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,save_yaml:0
|
||||
msgid "YAML file successfully created !"
|
||||
msgstr ""
|
||||
msgstr "Soubor YAML úspěšně vytvořen !"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_data,info:0
|
||||
#: wizard_view:base_module_record.module_record_data,save_yaml:0
|
||||
msgid "Result, paste this to your module's xml"
|
||||
msgstr ""
|
||||
msgstr "Výsledek, vložte jej do xml modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: selection:base_module_record.module_record_data,init,filter_cond:0
|
||||
#: selection:base_module_record.module_record_objects,init,filter_cond:0
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
msgstr "Vytvořeno"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_data,end:0
|
||||
#: wizard_view:base_module_record.module_record_objects,end:0
|
||||
msgid "Thanks For using Module Recorder"
|
||||
msgstr ""
|
||||
msgstr "Díky za použití Záznamníku modulů"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,website:0
|
||||
msgid "Documentation URL"
|
||||
msgstr ""
|
||||
msgstr "URL dokumentace"
|
||||
|
||||
#. module: base_module_record
|
||||
#: selection:base_module_record.module_record_data,init,filter_cond:0
|
||||
#: selection:base_module_record.module_record_objects,init,filter_cond:0
|
||||
msgid "Modified"
|
||||
msgstr ""
|
||||
msgstr "Změněno"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_data,init,record:0
|
||||
#: wizard_button:base_module_record.module_record_objects,init,record:0
|
||||
msgid "Record"
|
||||
msgstr ""
|
||||
msgstr "Zaznamenávat"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.module.module,shortdesc:base_module_record.module_meta_information
|
||||
msgid "Module Record"
|
||||
msgstr ""
|
||||
msgstr "Záznam modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_objects,info,save:0
|
||||
msgid "Continue"
|
||||
msgstr ""
|
||||
msgstr "Pokračovat"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.actions.wizard,name:base_module_record.wizard_base_module_record_data
|
||||
#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_module_record_data
|
||||
msgid "Export Customizations As Data File"
|
||||
msgstr ""
|
||||
msgstr "Exportovat vlastní úpravy jako datový soubor"
|
||||
|
||||
#. module: base_module_record
|
||||
#: code:addons/base_module_record/wizard/base_module_save.py:129
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
msgstr "Chyba"
|
||||
|
||||
#. module: base_module_record
|
||||
#: selection:base_module_record.module_record_objects,info,data_kind:0
|
||||
msgid "Normal Data"
|
||||
msgstr ""
|
||||
msgstr "Běžná data"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_data,end,end:0
|
||||
#: wizard_button:base_module_record.module_record_objects,end,end:0
|
||||
msgid "OK"
|
||||
msgstr ""
|
||||
msgstr "OK"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.ui.menu,name:base_module_record.menu_wizard_base_mod_rec
|
||||
msgid "Module Creation"
|
||||
msgstr ""
|
||||
msgstr "Vytvoření modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_objects,info,data_kind:0
|
||||
msgid "Type of Data"
|
||||
msgstr ""
|
||||
msgstr "Typ dat"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_view:base_module_record.module_record_objects,info:0
|
||||
msgid "Module Information"
|
||||
msgstr ""
|
||||
msgstr "Informace modulu"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,init,info_yaml:0
|
||||
#: wizard_field:base_module_record.module_record_objects,init,info_yaml:0
|
||||
msgid "YAML"
|
||||
msgstr ""
|
||||
msgstr "YAML"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_field:base_module_record.module_record_data,info,res_text:0
|
||||
#: wizard_field:base_module_record.module_record_data,save_yaml,res_text:0
|
||||
msgid "Result"
|
||||
msgstr ""
|
||||
msgstr "Výsledek"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_data,init,end:0
|
||||
#: wizard_button:base_module_record.module_record_objects,info,end:0
|
||||
#: wizard_button:base_module_record.module_record_objects,init,end:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Zrušit"
|
||||
|
||||
#. module: base_module_record
|
||||
#: wizard_button:base_module_record.module_record_objects,save,end:0
|
||||
#: wizard_button:base_module_record.module_record_objects,save_yaml,end:0
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
msgstr "Uzavřít"
|
||||
|
||||
#. module: base_module_record
|
||||
#: selection:base_module_record.module_record_data,init,filter_cond:0
|
||||
#: selection:base_module_record.module_record_objects,init,filter_cond:0
|
||||
msgid "Created & Modified"
|
||||
msgstr ""
|
||||
msgstr "Vytvořeno & upraveno"
|
||||
|
||||
#. module: base_module_record
|
||||
#: model:ir.module.module,description:base_module_record.module_meta_information
|
||||
|
@ -292,3 +296,25 @@ msgid ""
|
|||
"module.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Tento modul vám umožňuje vytvořit nový modul bez jakéhokoliv vývoje.\n"
|
||||
"Zaznamenává všechny operace nad objekty během relace zaznamenávání a\n"
|
||||
"vytváří .ZIP modul. Díky tomu můžete vytvořit váš vlastní modul přímo z\n"
|
||||
"klienta OpenERP.\n"
|
||||
"\n"
|
||||
"Tato verze pracuje pro vytváření a aktualizaci stávajících záznamů. "
|
||||
"Přepočítává\n"
|
||||
"závislosti a propojuje všechny datové typy pomůcek (many2one, many2many, "
|
||||
"...).\n"
|
||||
"Podporuje také pracovní toky a demonstrační/aktualziační data.\n"
|
||||
"\n"
|
||||
"Měl by vám pomoci jednoduše vytvářet znovu použitelné a zveřejnitelné "
|
||||
"moduly\n"
|
||||
"pro vlastní nastavení a demonstrační/testovací data.\n"
|
||||
"\n"
|
||||
"Jak jej použít:\n"
|
||||
"Spusťte průvodce Správa/Přizpůsobení/Vytváření modulů/Exportovat vlastní "
|
||||
"úpravy jako modul.\n"
|
||||
"Vyberte častoé kritéria pro záznam a objekty, které mají být zaznamenány a "
|
||||
"modul záznamu.\n"
|
||||
" "
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<field name="name">Start Configuration</field>
|
||||
<field name="model_id" ref="base.model_ir_actions_todo"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code" eval="'# obj is a browse_record and will provide stupid ids to method\n' 'action = obj.pool.get(\'ir.actions.todo\').action_launch(cr, uid, ' + str([ref('base_setup_installer_todo')]) + ', context=context)'"/>
|
||||
<field name="code" eval="'# obj is a browse_record and will provide stupid ids to method\n' 'action = pool.get(\'ir.actions.todo\').action_launch(cr, uid, ' + str([ref('base_setup_installer_todo')]) + ', context=context)'"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Add More Features" action="action_start_configurator" id="menu_view_base_module_configuration" parent="base.menu_config" type="server" icon="STOCK_EXECUTE" sequence="100"/>
|
||||
|
|
|
@ -42,7 +42,7 @@ _ref_vat = {
|
|||
'pt': 'PT123456789', 'ro': 'RO1234567897',
|
||||
'se': 'SE123456789701', 'si': 'SI12345679',
|
||||
'sk': 'SK0012345675', 'el': 'EL12345670',
|
||||
'mx': 'MXABCD831230T1B',
|
||||
'mx': 'MXABC123456T1B', 'no': 'NO123456785'
|
||||
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1104,33 @@ class res_partner(osv.osv):
|
|||
|
||||
#Valid format and valid date
|
||||
return True
|
||||
|
||||
|
||||
|
||||
# check_vat_no contributed by Rolv Råen (adEgo)
|
||||
def check_vat_no(self, vat):
|
||||
'''
|
||||
Check Norway VAT number.See http://www.brreg.no/english/coordination/number.html
|
||||
'''
|
||||
if len(vat) != 9:
|
||||
return False
|
||||
try:
|
||||
int(vat)
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
sum = (3 * int(vat[0])) + (2 * int(vat[1])) + \
|
||||
(7 * int(vat[2])) + (6 * int(vat[3])) + \
|
||||
(5 * int(vat[4])) + (4 * int(vat[5])) + \
|
||||
(3 * int(vat[6])) + (2 * int(vat[7]))
|
||||
|
||||
check = 11 -(sum % 11)
|
||||
if check == 11:
|
||||
check = 0
|
||||
if check == 10:
|
||||
# 10 is not a valid check digit for an organization number
|
||||
return False
|
||||
return check == int(vat[8])
|
||||
|
||||
res_partner()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -59,7 +59,7 @@ Creates a dashboard for CRM that includes:
|
|||
'base_action_rule',
|
||||
'base_setup',
|
||||
'process',
|
||||
'mail_gateway',
|
||||
'mail',
|
||||
'base_calendar',
|
||||
'resource',
|
||||
'board'
|
||||
|
@ -85,7 +85,6 @@ Creates a dashboard for CRM that includes:
|
|||
'wizard/crm_opportunity_to_phonecall_view.xml',
|
||||
'wizard/crm_partner_to_opportunity_view.xml',
|
||||
|
||||
'wizard/crm_send_email_view.xml',
|
||||
'wizard/crm_add_note_view.xml',
|
||||
'wizard/crm_merge_opportunities_view.xml',
|
||||
|
||||
|
|
|
@ -116,39 +116,12 @@ class crm_case_section(osv.osv):
|
|||
('code_uniq', 'unique (code)', 'The code of the sales team must be unique !')
|
||||
]
|
||||
|
||||
def _check_recursion(self, cr, uid, ids, context=None):
|
||||
|
||||
"""
|
||||
Checks for recursion level for sales team
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Sales team ids
|
||||
"""
|
||||
level = 100
|
||||
|
||||
while len(ids):
|
||||
cr.execute('select distinct parent_id from crm_case_section where id IN %s', (tuple(ids),))
|
||||
ids = filter(None, map(lambda x: x[0], cr.fetchall()))
|
||||
if not level:
|
||||
return False
|
||||
level -= 1
|
||||
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
|
||||
(osv.osv._check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
|
||||
]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
"""Overrides orm name_get method
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of sales team ids
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
"""Overrides orm name_get method"""
|
||||
if not isinstance(ids, list) :
|
||||
ids = [ids]
|
||||
res = []
|
||||
|
@ -174,13 +147,7 @@ class crm_case_categ(osv.osv):
|
|||
}
|
||||
|
||||
def _find_object_id(self, cr, uid, context=None):
|
||||
"""Finds id for case object
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
|
||||
"""Finds id for case object"""
|
||||
object_id = context and context.get('object_id', False) or False
|
||||
ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
|
||||
return ids and ids[0]
|
||||
|
@ -217,6 +184,9 @@ class crm_base(object):
|
|||
if not context.get('portal'):
|
||||
return False
|
||||
# was user.address_id.id, but address_id has been removed
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
if hasattr(user, 'partner_address_id') and user.partner_address_id:
|
||||
return user.partner_address_id
|
||||
return False
|
||||
|
||||
def _get_default_partner(self, cr, uid, context=None):
|
||||
|
@ -228,6 +198,8 @@ class crm_base(object):
|
|||
if not context.get('portal', False):
|
||||
return False
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
if hasattr(user, 'partner_address_id') and user.partner_address_id:
|
||||
return user.partner_address_id
|
||||
return user.company_id.partner_id.id
|
||||
|
||||
def _get_default_email(self, cr, uid, context=None):
|
||||
|
@ -255,9 +227,9 @@ class crm_base(object):
|
|||
|
||||
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
|
||||
"""This function returns value of partner email based on Partner Address
|
||||
@param ids: List of case IDs
|
||||
@param add: Id of Partner's address
|
||||
@email: Partner's email ID
|
||||
:param ids: List of case IDs
|
||||
:param add: Id of Partner's address
|
||||
:param email: Partner's email ID
|
||||
"""
|
||||
if not add:
|
||||
return {'value': {'email_from': False}}
|
||||
|
@ -269,9 +241,9 @@ class crm_base(object):
|
|||
|
||||
def onchange_partner_id(self, cr, uid, ids, part, email=False):
|
||||
"""This function returns value of partner address based on partner
|
||||
@param ids: List of case IDs
|
||||
@param part: Partner's id
|
||||
@email: Partner's email ID
|
||||
:param ids: List of case IDs
|
||||
:param part: Partner's id
|
||||
:param email: Partner's email ID
|
||||
"""
|
||||
data={}
|
||||
if part:
|
||||
|
@ -282,6 +254,7 @@ class crm_base(object):
|
|||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
"""Opens Case
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
for case in cases:
|
||||
|
@ -295,7 +268,7 @@ class crm_base(object):
|
|||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
"""Closes Case
|
||||
@param ids: List of case Ids
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
|
@ -306,7 +279,7 @@ class crm_base(object):
|
|||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
"""Cancels Case
|
||||
@param ids: List of case Ids
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
|
@ -317,6 +290,7 @@ class crm_base(object):
|
|||
|
||||
def case_pending(self, cr, uid, ids, *args):
|
||||
"""Marks case as pending
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
|
@ -326,13 +300,14 @@ class crm_base(object):
|
|||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
"""Resets case as draft
|
||||
:param ids: List of case Ids
|
||||
"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self.write(cr, uid, ids, {'state': 'draft', 'active': True})
|
||||
self._action(cr, uid, cases, 'draft')
|
||||
return True
|
||||
|
||||
|
||||
def _action(self, cr, uid, cases, state_to, scrit=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -357,13 +332,14 @@ class crm_case(crm_base):
|
|||
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, domain, order=order)
|
||||
if stage_ids:
|
||||
return stage_ids[0]
|
||||
return False
|
||||
|
||||
def stage_set(self, cr, uid, ids, stage_id, context=None):
|
||||
value = {}
|
||||
if hasattr(self,'onchange_stage_id'):
|
||||
value = self.onchange_stage_id(cr, uid, ids, stage_id)['value']
|
||||
value['stage_id'] = stage_id
|
||||
self.write(cr, uid, ids, value, context=context)
|
||||
return self.write(cr, uid, ids, value, context=context)
|
||||
|
||||
def stage_change(self, cr, uid, ids, op, order, context=None):
|
||||
if context is None:
|
||||
|
@ -377,25 +353,25 @@ class crm_case(crm_base):
|
|||
section_id = case.section_id.id
|
||||
next_stage_id = self.stage_find(cr, uid, section_id, [('sequence',op,seq)],order)
|
||||
if next_stage_id:
|
||||
self.stage_set(cr, uid, [case.id], next_stage_id, context=context)
|
||||
return self.stage_set(cr, uid, [case.id], next_stage_id, context=context)
|
||||
return False
|
||||
|
||||
def stage_next(self, cr, uid, ids, context=None):
|
||||
"""This function computes next stage for case from its current stage
|
||||
using available stage for that case type
|
||||
"""
|
||||
self.stage_change(cr, uid, ids, '>','sequence', context)
|
||||
return self.stage_change(cr, uid, ids, '>','sequence', context)
|
||||
|
||||
def stage_previous(self, cr, uid, ids, context=None):
|
||||
"""This function computes previous stage for case from its current
|
||||
stage using available stage for that case type
|
||||
"""
|
||||
self.stage_change(cr, uid, ids, '<', 'sequence desc', context)
|
||||
return self.stage_change(cr, uid, ids, '<', 'sequence desc', context)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
""" Overrides orm copy method.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
"""Overrides orm copy method to avoid copying messages,
|
||||
as well as date_closed and date_open columns if they
|
||||
exist."""
|
||||
if default is None:
|
||||
default = {}
|
||||
|
||||
|
@ -407,19 +383,11 @@ class crm_case(crm_base):
|
|||
default.update({ 'date_open': False })
|
||||
return super(osv.osv, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context=None):
|
||||
mailgate_pool = self.pool.get('mailgate.thread')
|
||||
return mailgate_pool.history(cr, uid, cases, keyword, history=history,\
|
||||
subject=subject, email=email, \
|
||||
details=details, email_from=email_from,\
|
||||
message_id=message_id, attach=attach, \
|
||||
context=context)
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
"""Opens Case
|
||||
"""
|
||||
"""Opens Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self._history(cr, uid, cases, _('Open'))
|
||||
self.message_append(cr, uid, cases, _('Open'))
|
||||
for case in cases:
|
||||
data = {'state': 'open', 'active': True }
|
||||
if not case.user_id:
|
||||
|
@ -429,11 +397,10 @@ class crm_case(crm_base):
|
|||
return True
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
"""Closes Case
|
||||
"""
|
||||
"""Closes Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self._history(cr, uid, cases, _('Close'))
|
||||
self.message_append(cr, uid, cases, _('Close'))
|
||||
self.write(cr, uid, ids, {'state': 'done',
|
||||
'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
})
|
||||
|
@ -444,12 +411,10 @@ class crm_case(crm_base):
|
|||
return True
|
||||
|
||||
def case_escalate(self, cr, uid, ids, *args):
|
||||
"""Escalates case to top level
|
||||
"""
|
||||
"""Escalates case to parent level"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
for case in cases:
|
||||
data = {'active': True}
|
||||
|
||||
if case.section_id.parent_id:
|
||||
data['section_id'] = case.section_id.parent_id.id
|
||||
if case.section_id.parent_id.change_responsible:
|
||||
|
@ -459,16 +424,15 @@ class crm_case(crm_base):
|
|||
raise osv.except_osv(_('Error !'), _('You can not escalate, You are already at the top level regarding your sales-team category.'))
|
||||
self.write(cr, uid, [case.id], data)
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self._history(cr, uid, cases, _('Escalate'))
|
||||
self.message_append(cr, uid, cases, _('Escalate'))
|
||||
self._action(cr, uid, cases, 'escalate')
|
||||
return True
|
||||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
"""Cancels Case
|
||||
"""
|
||||
"""Cancels Case"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self._history(cr, uid, cases, _('Cancel'))
|
||||
self.message_append(cr, uid, cases, _('Cancel'))
|
||||
self.write(cr, uid, ids, {'state': 'cancel',
|
||||
'active': True})
|
||||
self._action(cr, uid, cases, 'cancel')
|
||||
|
@ -478,56 +442,37 @@ class crm_case(crm_base):
|
|||
return True
|
||||
|
||||
def case_pending(self, cr, uid, ids, *args):
|
||||
"""Marks case as pending
|
||||
"""
|
||||
"""Marks case as pending"""
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self._history(cr, uid, cases, _('Pending'))
|
||||
self.message_append(cr, uid, cases, _('Pending'))
|
||||
self.write(cr, uid, ids, {'state': 'pending', 'active': True})
|
||||
self._action(cr, uid, cases, 'pending')
|
||||
return True
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
"""Resets case as draft
|
||||
"""
|
||||
state = 'draft'
|
||||
"""Resets case as draft"""
|
||||
state = 'draft'
|
||||
if 'crm.phonecall' in args:
|
||||
state = 'open'
|
||||
state = 'open'
|
||||
cases = self.browse(cr, uid, ids)
|
||||
cases[0].state # to fill the browse record cache
|
||||
self._history(cr, uid, cases, _('Draft'))
|
||||
self.message_append(cr, uid, cases, _('Draft'))
|
||||
self.write(cr, uid, ids, {'state': state, 'active': True})
|
||||
self._action(cr, uid, cases, state)
|
||||
return True
|
||||
|
||||
def remind_partner(self, cr, uid, ids, context=None, attach=False):
|
||||
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Remind Partner's IDs
|
||||
@param context: A standard dictionary for contextual values
|
||||
|
||||
"""
|
||||
|
||||
return self.remind_user(cr, uid, ids, context, attach,
|
||||
destination=False)
|
||||
|
||||
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case's IDs to remind
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
mail_message = self.pool.get('mail.message')
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if not destination and not case.email_from:
|
||||
return False
|
||||
if not case.user_id.user_email:
|
||||
return False
|
||||
|
||||
if destination and case.section_id.user_id:
|
||||
case_email = case.section_id.user_id.user_email
|
||||
else:
|
||||
|
@ -548,37 +493,31 @@ class crm_case(crm_base):
|
|||
|
||||
body = self.format_body(body)
|
||||
|
||||
attach_to_send = None
|
||||
attach_to_send = {}
|
||||
|
||||
if attach:
|
||||
attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', case.id)])
|
||||
attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas'])
|
||||
attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)
|
||||
attach_to_send = dict(map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send))
|
||||
|
||||
# Send an email
|
||||
subject = "Reminder: [%s] %s" % (str(case.id), case.name,)
|
||||
tools.email_send(
|
||||
# Send an email
|
||||
subject = "Reminder: [%s] %s" % (str(case.id), case.name, )
|
||||
mail_message.schedule_with_attach(cr, uid,
|
||||
src,
|
||||
[dest],
|
||||
subject,
|
||||
body,
|
||||
reply_to=case.section_id.reply_to or '',
|
||||
openobject_id=str(case.id),
|
||||
attach=attach_to_send
|
||||
model='crm.case',
|
||||
reply_to=case.section_id.reply_to,
|
||||
res_id=case.id,
|
||||
attachments=attach_to_send,
|
||||
context=context
|
||||
)
|
||||
self._history(cr, uid, [case], _('Send'), history=True, subject=subject, email=dest, details=body, email_from=src)
|
||||
|
||||
return True
|
||||
|
||||
def _check(self, cr, uid, ids=False, context=None):
|
||||
"""
|
||||
Function called by the scheduler to process cases for date actions
|
||||
Only works on not done and cancelled cases
|
||||
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""Function called by the scheduler to process cases for date actions
|
||||
Only works on not done and cancelled cases
|
||||
"""
|
||||
cr.execute('select * from crm_case \
|
||||
where (date_action_last<%s or date_action_last is null) \
|
||||
|
@ -597,9 +536,7 @@ class crm_case(crm_base):
|
|||
def format_mail(self, obj, body):
|
||||
return self.pool.get('base.action.rule').format_mail(obj, body)
|
||||
|
||||
def message_followers(self, cr, uid, ids, context=None):
|
||||
""" Get a list of emails of the people following this thread
|
||||
"""
|
||||
def message_thread_followers(self, cr, uid, ids, context=None):
|
||||
res = {}
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
l=[]
|
||||
|
@ -611,12 +548,7 @@ class crm_case(crm_base):
|
|||
return res
|
||||
|
||||
def _links_get(self, cr, uid, context=None):
|
||||
"""Gets links value for reference field
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
"""Gets links value for reference field"""
|
||||
obj = self.pool.get('res.request.link')
|
||||
ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, ids, ['object', 'name'], context)
|
||||
|
@ -632,10 +564,8 @@ class users(osv.osv):
|
|||
def create(self, cr, uid, vals, context=None):
|
||||
res = super(users, self).create(cr, uid, vals, context=context)
|
||||
section_obj=self.pool.get('crm.case.section')
|
||||
|
||||
if vals.get('context_section_id', False):
|
||||
if vals.get('context_section_id'):
|
||||
section_obj.write(cr, uid, [vals['context_section_id']], {'member_ids':[(4, res)]}, context)
|
||||
return res
|
||||
|
||||
users()
|
||||
|
||||
|
|
|
@ -40,12 +40,12 @@ class base_action_rule(osv.osv):
|
|||
'regex_history' : fields.char('Regular Expression on Case History', size=128),
|
||||
'act_section_id': fields.many2one('crm.case.section', 'Set Team to'),
|
||||
'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'),
|
||||
'act_mail_to_partner': fields.boolean('Mail to Partner', help="Check \
|
||||
this if you want the rule to send an email to the partner."),
|
||||
'act_mail_to_partner': fields.boolean('Mail to Partner',
|
||||
help="Check this if you want the rule to send an email to the partner."),
|
||||
}
|
||||
|
||||
|
||||
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context=None):
|
||||
mail_message = self.pool.get('mail.message')
|
||||
body = self.format_mail(obj, body)
|
||||
if not emailfrom:
|
||||
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.user_email:
|
||||
|
@ -58,15 +58,10 @@ this if you want the rule to send an email to the partner."),
|
|||
else:
|
||||
reply_to = emailfrom
|
||||
if not emailfrom:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_("No E-Mail ID Found for your Company address!"))
|
||||
return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
|
||||
raise osv.except_osv(_('Error!'), _("No E-Mail Found for your Company address!"))
|
||||
return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, res_id=obj.id)
|
||||
|
||||
def do_check(self, cr, uid, action, obj, context=None):
|
||||
""" @param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values"""
|
||||
ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context)
|
||||
|
||||
if hasattr(obj, 'section_id'):
|
||||
|
@ -74,9 +69,8 @@ this if you want the rule to send an email to the partner."),
|
|||
if hasattr(obj, 'categ_id'):
|
||||
ok = ok and (not action.trg_categ_id or action.trg_categ_id.id == obj.categ_id.id)
|
||||
|
||||
#Cheking for history
|
||||
#Cheking for history
|
||||
regex = action.regex_history
|
||||
result_history = True
|
||||
if regex:
|
||||
res = False
|
||||
ptrn = re.compile(str(regex))
|
||||
|
@ -85,23 +79,17 @@ this if you want the rule to send an email to the partner."),
|
|||
if _result:
|
||||
res = True
|
||||
break
|
||||
result_history = res
|
||||
ok = ok and (not regex or result_history)
|
||||
ok = ok and res
|
||||
|
||||
res_count = True
|
||||
if action.trg_max_history:
|
||||
res_count = False
|
||||
history_ids = filter(lambda x: x.history, obj.message_ids)
|
||||
history_ids = filter(lambda x: x.email_from, obj.message_ids)
|
||||
if len(history_ids) <= action.trg_max_history:
|
||||
res_count = True
|
||||
ok = ok and res_count
|
||||
ok = ok and res_count
|
||||
return ok
|
||||
|
||||
def do_action(self, cr, uid, action, model_obj, obj, context=None):
|
||||
""" @param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values """
|
||||
res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context)
|
||||
write = {}
|
||||
|
||||
|
@ -118,8 +106,8 @@ this if you want the rule to send an email to the partner."),
|
|||
write['email_cc'] = obj.act_email_cc
|
||||
|
||||
# Put state change by rule in communication history
|
||||
if hasattr(obj, 'state') and action.act_state:
|
||||
model_obj._history(cr, uid, [obj], _(action.act_state))
|
||||
if hasattr(obj, 'state') and hasattr(obj, 'message_append') and action.act_state:
|
||||
model_obj.message_append(cr, uid, [obj], _(action.act_state))
|
||||
|
||||
model_obj.write(cr, uid, [obj.id], write, context)
|
||||
emails = []
|
||||
|
@ -134,22 +122,12 @@ this if you want the rule to send an email to the partner."),
|
|||
|
||||
|
||||
def state_get(self, cr, uid, context=None):
|
||||
"""Gets available states for crm
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values """
|
||||
"""Gets available states for crm"""
|
||||
res = super(base_action_rule, self).state_get(cr, uid, context=context)
|
||||
return res + crm.AVAILABLE_STATES
|
||||
|
||||
def priority_get(self, cr, uid, context=None):
|
||||
"""@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values """
|
||||
res = super(base_action_rule, self).priority_get(cr, uid, context=context)
|
||||
return res + crm.AVAILABLE_PRIORITIES
|
||||
|
||||
base_action_rule()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -40,7 +40,15 @@ class crm_lead(crm_case, osv.osv):
|
|||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
_order = "priority,date_action,id desc"
|
||||
_inherit = ['mailgate.thread','res.partner.address']
|
||||
_inherit = ['mail.thread','res.partner.address']
|
||||
|
||||
# overridden because res.partner.address has an inconvenient name_get,
|
||||
# especially if base_contact is installed.
|
||||
def name_get(self, cr, user, ids, context=None):
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
return [(r['id'], tools.ustr(r[self._rec_name]))
|
||||
for r in self.read(cr, user, ids, [self._rec_name], context)]
|
||||
|
||||
def _compute_day(self, cr, uid, ids, fields, args, context=None):
|
||||
"""
|
||||
|
@ -101,8 +109,8 @@ class crm_lead(crm_case, osv.osv):
|
|||
|
||||
def _history_search(self, cr, uid, obj, name, args, context=None):
|
||||
res = []
|
||||
msg_obj = self.pool.get('mailgate.message')
|
||||
message_ids = msg_obj.search(cr, uid, [('history','=',True), ('name', args[0][1], args[0][2])], context=context)
|
||||
msg_obj = self.pool.get('mail.message')
|
||||
message_ids = msg_obj.search(cr, uid, [('email_from','!=',False), ('subject', args[0][1], args[0][2])], context=context)
|
||||
lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context)
|
||||
|
||||
if lead_ids:
|
||||
|
@ -115,8 +123,8 @@ class crm_lead(crm_case, osv.osv):
|
|||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
res[obj.id] = ''
|
||||
for msg in obj.message_ids:
|
||||
if msg.history:
|
||||
res[obj.id] = msg.name
|
||||
if msg.email_from:
|
||||
res[obj.id] = msg.subject
|
||||
break
|
||||
return res
|
||||
|
||||
|
@ -163,7 +171,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
|
||||
|
||||
|
||||
|
@ -178,6 +186,12 @@ class crm_lead(crm_case, osv.osv):
|
|||
'date_action': fields.date('Next Action Date'),
|
||||
'title_action': fields.char('Next Action', size=64),
|
||||
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
|
||||
'color': fields.integer('Color Index'),
|
||||
'partner_address_name': fields.related('partner_address_id', 'name', type='char', string='Partner Contact Name', readonly=True),
|
||||
'company_currency': fields.related('company_id', 'currency_id', 'symbol', type='char', string='Company Currency', readonly=True),
|
||||
'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
|
||||
'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True),
|
||||
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -189,6 +203,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
'section_id': crm_case._get_section,
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'color': 0,
|
||||
#'stage_id': _get_stage_id,
|
||||
}
|
||||
|
||||
|
@ -304,6 +319,21 @@ class crm_lead(crm_case, osv.osv):
|
|||
self.log(cr, uid, l.id, message)
|
||||
return res
|
||||
|
||||
def set_priority(self, cr, uid, ids, priority):
|
||||
"""Set lead priority
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'priority' : priority})
|
||||
|
||||
def set_high_priority(self, cr, uid, ids, *args):
|
||||
"""Set lead priority to high
|
||||
"""
|
||||
return self.set_priority(cr, uid, ids, '1')
|
||||
|
||||
def set_normal_priority(self, cr, uid, ids, *args):
|
||||
"""Set lead priority to normal
|
||||
"""
|
||||
return self.set_priority(cr, uid, ids, '3')
|
||||
|
||||
def convert_opportunity(self, cr, uid, ids, context=None):
|
||||
""" Precomputation for converting lead to opportunity
|
||||
"""
|
||||
|
@ -335,16 +365,14 @@ class crm_lead(crm_case, osv.osv):
|
|||
}
|
||||
return value
|
||||
|
||||
def message_new(self, cr, uid, msg, context=None):
|
||||
""" Automatically calls when new email message arrives
|
||||
"""
|
||||
mailgate_pool = self.pool.get('email.server.tools')
|
||||
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
||||
"""Automatically calls when new email message arrives"""
|
||||
res_id = super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
|
||||
subject = msg.get('subject') or _("No Subject")
|
||||
body = msg.get('body_text')
|
||||
|
||||
subject = msg.get('subject') or _("No Subject")
|
||||
body = msg.get('body')
|
||||
msg_from = msg.get('from')
|
||||
priority = msg.get('priority')
|
||||
|
||||
vals = {
|
||||
'name': subject,
|
||||
'email_from': msg_from,
|
||||
|
@ -352,45 +380,27 @@ class crm_lead(crm_case, osv.osv):
|
|||
'description': body,
|
||||
'user_id': False,
|
||||
}
|
||||
if msg.get('priority', False):
|
||||
if priority:
|
||||
vals['priority'] = priority
|
||||
vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
|
||||
self.write(cr, uid, [res_id], vals, context)
|
||||
return res_id
|
||||
|
||||
res = mailgate_pool.get_partner(cr, uid, msg.get('from') or msg.get_unixfrom())
|
||||
if res:
|
||||
vals.update(res)
|
||||
|
||||
res = self.create(cr, uid, vals, context)
|
||||
attachents = msg.get('attachments', [])
|
||||
for attactment in attachents or []:
|
||||
data_attach = {
|
||||
'name': attactment,
|
||||
'datas':binascii.b2a_base64(str(attachents.get(attactment))),
|
||||
'datas_fname': attactment,
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self._name,
|
||||
'res_id': res,
|
||||
}
|
||||
self.pool.get('ir.attachment').create(cr, uid, data_attach)
|
||||
|
||||
return res
|
||||
|
||||
def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None):
|
||||
"""
|
||||
@param ids: List of update mail’s IDs
|
||||
"""
|
||||
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
ids = [ids]
|
||||
|
||||
super(crm_lead, self).message_update(cr, uid, ids, msg, context=context)
|
||||
|
||||
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
|
||||
vals['priority'] = msg.get('priority')
|
||||
|
||||
maps = {
|
||||
'cost':'planned_cost',
|
||||
'revenue': 'planned_revenue',
|
||||
'probability':'probability'
|
||||
}
|
||||
vls = {}
|
||||
for line in msg['body'].split('\n'):
|
||||
for line in msg['body_text'].split('\n'):
|
||||
line = line.strip()
|
||||
res = tools.misc.command_re.match(line)
|
||||
if res and maps.get(res.group(1).lower()):
|
||||
|
@ -408,12 +418,6 @@ class crm_lead(crm_case, osv.osv):
|
|||
res = self.write(cr, uid, [case.id], values, context=context)
|
||||
return res
|
||||
|
||||
def msg_send(self, cr, uid, id, *args, **argv):
|
||||
""" Send The Message
|
||||
@param ids: List of email’s IDs
|
||||
"""
|
||||
return True
|
||||
|
||||
def action_makeMeeting(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This opens Meeting's calendar view to schedule meeting on current Opportunity
|
||||
|
@ -459,24 +463,6 @@ class crm_lead(crm_case, osv.osv):
|
|||
}
|
||||
return value
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
if 'date_closed' in vals:
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
if 'stage_id' in vals and vals['stage_id']:
|
||||
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
|
||||
self.history(cr, uid, ids, _("Changed Stage to: %s") % stage_obj.name, details=_("Changed Stage to: %s") % stage_obj.name)
|
||||
message=''
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if case.type == 'lead' or context.get('stage_type',False)=='lead':
|
||||
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
|
||||
elif case.type == 'opportunity':
|
||||
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
|
||||
self.log(cr, uid, case.id, message)
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for lead in self.browse(cr, uid, ids, context):
|
||||
|
@ -486,6 +472,26 @@ class crm_lead(crm_case, osv.osv):
|
|||
return super(crm_lead, self).unlink(cr, uid, ids, context)
|
||||
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
if 'date_closed' in vals:
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
if 'stage_id' in vals and vals['stage_id']:
|
||||
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
|
||||
text = _("Changed Stage to: %s") % stage_obj.name
|
||||
self.message_append(cr, uid, ids, text, body_text=text, context=context)
|
||||
message=''
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if case.type == 'lead' or context.get('stage_type',False)=='lead':
|
||||
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
|
||||
elif case.type == 'opportunity':
|
||||
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
|
||||
self.log(cr, uid, case.id, message)
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context)
|
||||
|
||||
crm_lead()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -97,10 +97,10 @@
|
|||
</group>
|
||||
<group colspan="2" col="3">
|
||||
<separator string="Communication" colspan="4" col="3"/>
|
||||
<field name="email_from" widget="email"/><button string="Mail"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.lead'}"
|
||||
icon="terp-mail-message-new" type="action" colspan="1"/>
|
||||
<field name="email_from" widget="email"/>
|
||||
<button string="Mail"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action" colspan="1"/>
|
||||
<newline/>
|
||||
<field name="phone"/>
|
||||
<newline/>
|
||||
|
@ -174,52 +174,53 @@
|
|||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" widget="char" size="512"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
<group col="2" colspan="2" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="email_from"/>
|
||||
<field name="date"/>
|
||||
<field name="email_to" size="512"/>
|
||||
<field name="email_cc" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
|
||||
<field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
|
||||
<field name="history" invisible="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<field name="description" colspan="4" nolabel="1"/>
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<field name="date"/>
|
||||
<field name="email_cc" size="512" attrs="{'invisible': [('email_from', '=', False)]}"/>
|
||||
</group>
|
||||
<field name="subject" colspan="4" widget="char" attrs="{'invisible': [('email_from', '=', False)]}" size="512"/>
|
||||
<field name="display_text" colspan="4" attrs="{'invisible': [('email_from', '!=', False)]}"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1"/>
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply'}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</page>
|
||||
<page string="Attachments" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.lead'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
@ -297,60 +298,63 @@
|
|||
<field name="model">crm.lead</field>
|
||||
<field name="type">kanban</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<kanban default_group_by="stage_id">
|
||||
<field name="state"/>
|
||||
<field name="color"/>
|
||||
<field name="priority"/>
|
||||
<field name="planned_revenue"/>
|
||||
<field name="user_email"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_box oe_kanban_color_border #{__kanban_color(state.raw_value)}">
|
||||
<div class="oe_kanban_box_header oe_kanban_color_bgdark oe_kanban_color_border oe_kanban_draghandle">
|
||||
<h6 class="oe_kanban_left"><field name="name"/></h6>
|
||||
<h5 class="oe_kanban_right" style="vertical-align: top">
|
||||
<field name="planned_revenue"/>
|
||||
<img src="http://www.gravatar.com/avatar/2eb60ad22dadcf4dc456b28390a80268.png" style="border-radius: 2px" width="20" height="20"/>
|
||||
</h5>
|
||||
<br class="oe_kanban_clear"/>
|
||||
</div>
|
||||
<t t-set="color" t-value="kanban_color(record.color.raw_value || record.state.raw_value)"/>
|
||||
<div t-att-class="color + (record.priority.raw_value == 1 ? ' oe_kanban_color_alert' : '')">
|
||||
<div class="oe_kanban_box oe_kanban_color_border">
|
||||
<table class="oe_kanban_table oe_kanban_box_header oe_kanban_color_bgdark oe_kanban_color_border oe_kanban_draghandle">
|
||||
<tr>
|
||||
<td class="oe_kanban_title3" align="left" valign="middle">
|
||||
<a t-if="record.priority.raw_value == 1" icon="star-on" type="object" name="set_normal_priority"/>
|
||||
<a t-if="record.priority.raw_value != 1" icon="star-off" type="object" name="set_high_priority" style="opacity:0.6; filter:alpha(opacity=60);"/>
|
||||
<field name="partner_id"/>
|
||||
</td>
|
||||
<td class="oe_kanban_title2" align="right" valign="middle" t-if="record.planned_revenue.raw_value" nowrap="nowrap">
|
||||
<t t-esc="Math.round(record.planned_revenue.value)"/> <field name="company_currency"/>
|
||||
</td>
|
||||
<td valign="top" width="22"><img t-att-src="kanban_gravatar(record.user_email.value, 22)" class="oe_kanban_gravatar"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="oe_kanban_box_content oe_kanban_color_bglight">
|
||||
<div class="oe_kanban_right oe_kanban_small">
|
||||
<field name="user_id"/>
|
||||
<div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_box_show_onclick_trigger">
|
||||
<div class="oe_kanban_right oe_kanban_small">
|
||||
<field name="user_login"/>
|
||||
</div>
|
||||
<div>
|
||||
<b><field name="partner_address_name"/></b>
|
||||
</div>
|
||||
<div>
|
||||
<field name="name"/>
|
||||
</div>
|
||||
<div style="padding-left: 0.5em">
|
||||
<i><field name="date_action"/><t t-if="record.date_action.raw_value"> : </t><field name="title_action"/></i>
|
||||
</div>
|
||||
</div>
|
||||
<br class="oe_kanban_clear"/>
|
||||
|
||||
<b><field name="partner_address_id"/></b><br/>
|
||||
<field name="description"/><br/>
|
||||
<field name="date_action"/><t t-if="date_action.raw_value">: </t><field name="title_action"/>
|
||||
</div>
|
||||
|
||||
<div class="oe_kanban_buttons_set oe_kanban_color_border oe_kanban_color_bglight oe_kanban_box_show_onclick">
|
||||
<div class="oe_kanban_left">
|
||||
<a string="Send New Email" class="oe_kanban_color_border"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.lead'}"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
|
||||
<a string="Schedule/Log Call" class="oe_kanban_color_border"
|
||||
name="%(opportunity2phonecall_act)d"
|
||||
icon="terp-call-start" type="action"/>
|
||||
|
||||
<a string="Add Internal Note" class="oe_kanban_color_border"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action"/>
|
||||
|
||||
<a name="action_makeMeeting" type="object" class="oe_kanban_color_border"
|
||||
string="Schedule Meeting" icon="gtk-redo" />
|
||||
<div class="oe_kanban_buttons_set oe_kanban_color_border oe_kanban_color_bglight oe_kanban_box_show_onclick">
|
||||
<div class="oe_kanban_left">
|
||||
<a string="Edit" icon="gtk-edit" type="edit"/>
|
||||
<a string="Delete" icon="gtk-close" type="delete"/>
|
||||
<a string="Change Color" icon="color-picker" type="color" name="color"/>
|
||||
<a string="Send New Email" name="%(mail.action_email_compose_message_wizard)d" icon="terp-mail-message-new" type="action"/>
|
||||
<a string="Schedule/Log Call" name="%(opportunity2phonecall_act)d" icon="terp-call-start" type="action"/>
|
||||
<a string="Add Internal Note" name="%(crm.action_crm_add_note)d" context="{'model': 'crm.lead' }" icon="terp-document-new" type="action"/>
|
||||
<a name="action_makeMeeting" type="object" string="Schedule Meeting" icon="gtk-redo" />
|
||||
</div>
|
||||
<div class="oe_kanban_right">
|
||||
<a name="case_pending" string="Pending" states="draft,open" type="object" icon="lead-stage-pending" />
|
||||
<a name="case_mark_won" string="Mark Won" states="open,pending" type="object" icon="lead-stage-won" />
|
||||
<a name="case_mark_lost" string="Mark Lost" states="open,pending" type="object" icon="lead-stage-lost" />
|
||||
</div>
|
||||
<br class="oe_kanban_clear"/>
|
||||
</div>
|
||||
<div class="oe_kanban_right">
|
||||
<a name="case_cancel" string="Cancel" states="draft" type="object" icon="gtk-cancel" />
|
||||
<a name="case_mark_lost" string="Mark Lost" states="open,pending" type="object" icon="gtk-cancel" />
|
||||
<a name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert" />
|
||||
<a name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward" />
|
||||
<a name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause" />
|
||||
<a name="case_escalate" string="Escalate" states="open,pending" type="object" icon="gtk-go-up" />
|
||||
<a name="case_mark_won" string="Mark Won" states="open,pending" type="object" icon="gtk-apply" />
|
||||
</div>
|
||||
<br class="oe_kanban_clear"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
@ -492,7 +496,7 @@
|
|||
<group col="3" colspan="2">
|
||||
<field name="email_from" string="Email" />
|
||||
<button string="Mail"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail':'new', 'model': 'crm.lead'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
</group>
|
||||
|
@ -552,58 +556,56 @@
|
|||
<field name="optout" on_change="on_change_optout(optout)"/>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="Communication & History" groups="base.group_extended">
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" string="Global CC" widget="char" size="512"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
<field name="email_from"/>
|
||||
<field name="date"/>
|
||||
<field name="email_to" size="512"/>
|
||||
<field name="email_cc" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
|
||||
<field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
|
||||
<field name="history" invisible="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
|
||||
<field name="description" colspan="4" nolabel="1"/>
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</group>
|
||||
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" widget="char" size="512"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
<group col="2" colspan="2" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="email_from"/>
|
||||
<field name="email_to" size="512"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<field name="date"/>
|
||||
<field name="email_cc" size="512" attrs="{'invisible': [('email_from', '=', False)]}"/>
|
||||
</group>
|
||||
<field name="subject" colspan="4" widget="char" attrs="{'invisible': [('email_from', '=', False)]}" size="512"/>
|
||||
<field name="display_text" colspan="4" attrs="{'invisible': [('email_from', '!=', False)]}"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1"/>
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply'}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.lead'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
<page string="Attachments" attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group col="2" colspan="2">
|
||||
|
|
|
@ -45,12 +45,12 @@ class crm_meeting(crm_base, osv.osv):
|
|||
_inherit = "calendar.event"
|
||||
_columns = {
|
||||
# From crm.case
|
||||
'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
|
||||
'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
|
||||
domain="[('partner_id','=',partner_id)]", states={'done': [('readonly', True)]}),
|
||||
domain="[('partner_id','=',partner_id)]", states={'done': [('readonly', True)]}),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', states={'done': [('readonly', True)]}, \
|
||||
select=True, help='Sales team to which Case belongs to.'),
|
||||
select=True, help='Sales team to which Case belongs to.'),
|
||||
'email_from': fields.char('Email', size=128, states={'done': [('readonly', True)]}, help="These people will receive email."),
|
||||
'id': fields.integer('ID'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
|
@ -67,7 +67,7 @@ class crm_meeting(crm_base, osv.osv):
|
|||
'event_id', 'attendee_id', 'Attendees', states={'done': [('readonly', True)]}),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'state': fields.selection([('open', 'Confirmed'),
|
||||
('draft', 'Unconfirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
|
@ -75,7 +75,7 @@ class crm_meeting(crm_base, osv.osv):
|
|||
size=16, readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'state': 'draft',
|
||||
'state': 'draft',
|
||||
'active': 1,
|
||||
'user_id': lambda self, cr, uid, ctx: uid,
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ class res_users(osv.osv):
|
|||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
user_id = super(res_users, self).create(cr, uid, data, context=context)
|
||||
|
||||
|
||||
# add shortcut unless 'noshortcut' is True in context
|
||||
if not(context and context.get('noshortcut', False)):
|
||||
data_obj = self.pool.get('ir.model.data')
|
||||
|
@ -150,7 +150,6 @@ class res_users(osv.osv):
|
|||
except:
|
||||
# Tolerate a missing shortcut. See product/product.py for similar code.
|
||||
logging.getLogger('orm').debug('Skipped meetings shortcut for user "%s"', data.get('name','<new'))
|
||||
|
||||
return user_id
|
||||
|
||||
res_users()
|
||||
|
|
|
@ -36,18 +36,18 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
# From crm.case
|
||||
'id': fields.integer('ID'),
|
||||
'name': fields.char('Call Summary', size=64),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
|
||||
select=True, help='Sales team to which Case belongs to.'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
select=True, help='Sales team to which Case belongs to.'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'description': fields.text('Description'),
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'description': fields.text('Description'),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('open', 'Todo'),
|
||||
|
@ -57,24 +57,24 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
], 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Todo\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
\nWhen the call is over, the state is set to \'Held\'.\
|
||||
\nIf the call needs to be done then the state is set to \'Not Held\'.'),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date_open': fields.datetime('Opened', readonly=True),
|
||||
# phonecall fields
|
||||
'duration': fields.float('Duration', help="Duration in Minutes"),
|
||||
'duration': fields.float('Duration', help="Duration in Minutes"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="['|',('section_id','=',section_id),('section_id','=',False),\
|
||||
('object_id.model', '=', 'crm.phonecall')]"),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
('object_id.model', '=', 'crm.phonecall')]"),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_contact': fields.related('partner_address_id', 'name', \
|
||||
type="char", string="Contact", size=128),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
type="char", string="Contact", size=128),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
}
|
||||
|
||||
def _get_default_state(self, cr, uid, context=None):
|
||||
|
@ -83,17 +83,14 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
return 'open'
|
||||
|
||||
_defaults = {
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'state': _get_default_state,
|
||||
'user_id': lambda self,cr,uid,ctx: uid,
|
||||
'active': 1,
|
||||
'active': 1,
|
||||
}
|
||||
|
||||
|
||||
|
||||
# From crm.case
|
||||
|
||||
# From crm.case
|
||||
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
|
||||
res = super(crm_phonecall, self).onchange_partner_address_id(cr, uid, ids, add, email)
|
||||
res.setdefault('value', {})
|
||||
|
@ -176,23 +173,23 @@ class crm_phonecall(crm_base, osv.osv):
|
|||
id3 = data_obj.browse(cr, uid, id3, context=context).res_id
|
||||
|
||||
context = {
|
||||
'default_phonecall_id': phonecall.id,
|
||||
'default_partner_id': phonecall.partner_id and phonecall.partner_id.id or False,
|
||||
'default_email': phonecall.email_from ,
|
||||
'default_phonecall_id': phonecall.id,
|
||||
'default_partner_id': phonecall.partner_id and phonecall.partner_id.id or False,
|
||||
'default_email': phonecall.email_from ,
|
||||
'default_name': phonecall.name
|
||||
}
|
||||
|
||||
value = {
|
||||
'name': _('Meetings'),
|
||||
'domain' : "[('user_id','=',%s)]" % (uid),
|
||||
'context': context,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'calendar,form,tree',
|
||||
'res_model': 'crm.meeting',
|
||||
'view_id': False,
|
||||
'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'search_view_id': res['res_id'],
|
||||
'name': _('Meetings'),
|
||||
'domain' : "[('user_id','=',%s)]" % (uid),
|
||||
'context': context,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'calendar,form,tree',
|
||||
'res_model': 'crm.meeting',
|
||||
'view_id': False,
|
||||
'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'search_view_id': res['res_id'],
|
||||
'nodestroy': True
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<notebook colspan="4">
|
||||
<page string="Sales Team">
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Mailgateway" colspan="2"/>
|
||||
<separator string="Mail Gateway" colspan="2"/>
|
||||
<field name="reply_to" select="2"/>
|
||||
</group>
|
||||
<group col="2" colspan="1">
|
||||
|
|
|
@ -121,7 +121,7 @@ class crm_lead_report(osv.osv):
|
|||
c.planned_revenue,
|
||||
c.planned_revenue*(c.probability/100) as probable_revenue,
|
||||
1 as nbr,
|
||||
(SELECT count(id) FROM mailgate_message WHERE model='crm.lead' AND res_id=c.id AND history=True) AS email,
|
||||
(SELECT count(id) FROM mail_message WHERE model='crm.lead' AND res_id=c.id AND email_from is not null) AS email,
|
||||
date_trunc('day',c.create_date) as create_date,
|
||||
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
|
||||
abs(extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24)) as delay_expected,
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
<field name="model">crm.lead.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Opportunities Analysis">
|
||||
<tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " string="Opportunities Analysis">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="creation_month" invisible="1"/>
|
||||
<field name="deadline_month" invisible="1"/>
|
||||
|
|
|
@ -29,15 +29,15 @@
|
|||
"access_res_partner_manager","res.partner.crm.manager","base.model_res_partner","base.group_sale_manager",1,0,0,0
|
||||
"access_res_partner_address_manager","res.partner.address.crm.user.manager","base.model_res_partner_address","base.group_sale_manager",1,0,0,0
|
||||
"access_res_partner_category_manager","res.partner.category.crm.manager","base.model_res_partner_category","base.group_sale_manager",1,0,0,0
|
||||
"mail_gateway_mailgate_message_manager","mail_gateway.mailgate.message.manager","mail_gateway.model_mailgate_message","base.group_sale_manager",1,0,0,0
|
||||
"mail_gateway_mailgate_thread_manager","mail_gateway.mailgate.thread.manager","mail_gateway.model_mailgate_thread","base.group_sale_manager",1,1,1,1
|
||||
"mail_mail_message_manager","mail.message.manager","mail.model_mail_message","base.group_sale_manager",1,0,0,0
|
||||
"mail_thread_manager","mail.thread.manager","mail.model_mail_thread","base.group_sale_manager",1,1,1,1
|
||||
"access_calendar_attendee_crm_user","calendar.attendee.crm.user","model_calendar_attendee","base.group_sale_salesman",1,1,1,0
|
||||
"access_calendar_attendee_crm_manager","calendar.attendee.crm.manager","model_calendar_attendee","base.group_sale_manager",1,1,1,1
|
||||
"access_res_partner","res.partner.crm.user","base.model_res_partner","base.group_sale_salesman",1,1,1,0
|
||||
"access_res_partner_address","res.partner.address.crm.user","base.model_res_partner_address","base.group_sale_salesman",1,1,1,0
|
||||
"access_res_partner_category","res.partner.category.crm.user","base.model_res_partner_category","base.group_sale_salesman",1,1,1,0
|
||||
"mail_gateway_mailgate_thread","mail_gateway.mailgate.thread","mail_gateway.model_mailgate_thread","base.group_sale_salesman",1,1,1,1
|
||||
"mail_gateway_mailgate_message_user","mail_gateway.mailgate.message.user","mail_gateway.model_mailgate_message","base.group_sale_salesman",1,1,1,1
|
||||
"mail_mailgate_thread","mail.thread","mail.model_mail_thread","base.group_sale_salesman",1,1,1,1
|
||||
"mail_gateway_mail_message_user","mail.message.user","mail.model_mail_message","base.group_sale_salesman",1,1,1,1
|
||||
"access_crm_case_categ_manager","crm.case.categ manager","model_crm_case_categ","base.group_sale_manager",1,1,1,1
|
||||
"access_base_action_rule_manager","base.action.rule manager","model_base_action_rule","base.group_sale_manager",1,1,1,1
|
||||
"access_crm_lead_report_user","crm.lead.report user","model_crm_lead_report","base.group_sale_salesman",1,1,1,1
|
||||
|
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import crm_send_email
|
||||
import mail_compose_message
|
||||
import crm_add_note
|
||||
|
||||
import crm_lead_to_partner
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
from crm import crm
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import base64
|
||||
from mail.mail_message import truncate_text
|
||||
|
||||
AVAILABLE_STATES = crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')]
|
||||
|
||||
|
||||
class crm_add_note(osv.osv_memory):
|
||||
"""Adds a new note to the case."""
|
||||
_name = 'crm.add.note'
|
||||
|
@ -14,8 +13,11 @@ class crm_add_note(osv.osv_memory):
|
|||
_columns = {
|
||||
'body': fields.text('Note Body', required=True),
|
||||
'state': fields.selection(AVAILABLE_STATES, string='Set New State To',
|
||||
required=True),
|
||||
'attachment_ids' : fields.one2many('crm.send.mail.attachment', 'wizard_id'),
|
||||
required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': 'unchanged'
|
||||
}
|
||||
|
||||
def action_add(self, cr, uid, ids, context=None):
|
||||
|
@ -32,14 +34,8 @@ class crm_add_note(osv.osv_memory):
|
|||
case_list = case_pool.browse(cr, uid, context['active_ids'],
|
||||
context=context)
|
||||
case = case_list[0]
|
||||
user_obj = self.pool.get('res.users')
|
||||
user_name = user_obj.browse(cr, uid, [uid], context=context)[0].name
|
||||
attach = [
|
||||
(x.name, base64.decodestring(x.binary)) for x in obj.attachment_ids
|
||||
]
|
||||
case_pool.history(cr, uid, [case], self.pool.get('mailgate.message').truncate_data(cr, uid, obj.body, context=context), history=False,
|
||||
details=obj.body, email_from=user_name, attach=attach)
|
||||
|
||||
case_pool.message_append(cr, uid, [case], truncate_text(obj.body),
|
||||
body_text=obj.body)
|
||||
if obj.state == 'unchanged':
|
||||
pass
|
||||
elif obj.state == 'done':
|
||||
|
@ -52,11 +48,4 @@ class crm_add_note(osv.osv_memory):
|
|||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
"""
|
||||
return {'state': u'unchanged'}
|
||||
|
||||
|
||||
crm_add_note()
|
||||
|
|
|
@ -132,26 +132,25 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
vals['partner_address_id'] = False
|
||||
|
||||
lead.write(vals, context=context)
|
||||
leads.history(cr, uid, [lead], _('Converted to opportunity'), details='Converted to Opportunity', context=context)
|
||||
text = _('Converted to opportunity')
|
||||
leads.message_append(cr, uid, [lead], text, body_text=text, context=context)
|
||||
if lead.partner_id:
|
||||
msg_ids = [ x.id for x in lead.message_ids]
|
||||
self.pool.get('mailgate.message').write(cr, uid, msg_ids, {
|
||||
self.pool.get('mail.message').write(cr, uid, msg_ids, {
|
||||
'partner_id': lead.partner_id.id
|
||||
}, context=context)
|
||||
leads.log(cr, uid, lead.id, _("Lead '%s' has been converted to an opportunity.") % lead.name)
|
||||
|
||||
def send_mail_to_salesman(self, lead):
|
||||
def send_mail_to_salesman(self, cr, uid, lead):
|
||||
email_to = lead.user_id and lead.user_id.user_email
|
||||
if not email_to:
|
||||
return
|
||||
return False
|
||||
message_pool = self.pool.get('mail.message')
|
||||
email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
|
||||
partner = lead.partner_id and lead.partner_id.name or lead.partner_name
|
||||
partner = lead.partner_id and lead.partner_id.name or lead.partner_name
|
||||
subject = "lead %s converted into opportunity" % lead.name
|
||||
body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
|
||||
try :
|
||||
tools.email_send(email_from, [email_to], subject, body)
|
||||
except:
|
||||
pass
|
||||
body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
|
||||
return message_pool.schedule_with_attach(cr, uid, email_from, [email_to], subject, body)
|
||||
|
||||
def action_apply(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
|
@ -205,7 +204,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
partner_id = False
|
||||
|
||||
self._convert(cr, uid, ids, lead, partner_id, stage_ids, context=context)
|
||||
self.send_mail_to_salesman(lead)
|
||||
self.send_mail_to_salesman(cr, uid, lead)
|
||||
#If we convert in mass, don't merge if there is no other opportunity but no warning
|
||||
if data.name == 'merge' and (len(data.opportunity_ids) > 1 or not context.get('mass_convert') ):
|
||||
merge_obj = self.pool.get('crm.merge.opportunity')
|
||||
|
|
|
@ -49,14 +49,9 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
|
||||
|
||||
def get_attachments(self, cr, uid, id, context=None):
|
||||
attach_obj = self.pool.get('ir.attachment')
|
||||
attach_ids = attach_obj.search(cr, uid, [('res_model' , '=', 'crm.lead'), ('res_id', '=', id)])
|
||||
return attach_ids
|
||||
|
||||
def set_attachements_res_id(self, cr, uid, op_id, attach_ids, context=None):
|
||||
attach_obj = self.pool.get('ir.attachment')
|
||||
attach_obj.write(cr, uid, attach_ids, {'res_id' : op_id})
|
||||
|
||||
proxy = self.pool.get('ir.attachment')
|
||||
ids = proxy.search(cr, uid, [('res_model', '=', 'crm.lead'), ('res_id', '=', id)], context=context)
|
||||
return proxy.browse(cr, uid, ids, context=context)
|
||||
|
||||
def find_oldest(self, cr, uid, op_ids, context=None):
|
||||
if not context:
|
||||
|
@ -70,9 +65,9 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
return False
|
||||
opps = lead_obj.browse(cr, uid, [op_id[0]], context=context)
|
||||
return opps[0]
|
||||
|
||||
|
||||
def _update_data(self, op_ids, oldest_opp):
|
||||
data = {
|
||||
data = {
|
||||
'partner_id': self._get_first_not_null_id('partner_id', op_ids, oldest_opp), # !!
|
||||
'title': self._get_first_not_null_id('title', op_ids, oldest_opp),
|
||||
'name' : self._get_first_not_null('name', op_ids, oldest_opp), #not lost
|
||||
|
@ -105,16 +100,15 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
'email_from' : self._get_first_not_null('email_from', op_ids, oldest_opp),
|
||||
'email_cc' : self._get_first_not_null('email_cc', op_ids, oldest_opp),
|
||||
'partner_name' : self._get_first_not_null('partner_name', op_ids, oldest_opp),
|
||||
|
||||
}
|
||||
return data
|
||||
}
|
||||
return data
|
||||
|
||||
def merge(self, cr, uid, op_ids, context=None):
|
||||
"""
|
||||
@param opp_ids : list of opportunities ids to merge
|
||||
:param opp_ids: list of opportunities ids to merge
|
||||
"""
|
||||
opp_obj = self.pool.get('crm.lead')
|
||||
message_obj = self.pool.get('mailgate.message')
|
||||
message_obj = self.pool.get('mail.message')
|
||||
|
||||
lead_ids = context and context.get('lead_ids', []) or []
|
||||
|
||||
|
@ -130,15 +124,23 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
else:
|
||||
first_opportunity = opportunities_list[0]
|
||||
tail_opportunities = opportunities_list[1:]
|
||||
|
||||
|
||||
|
||||
data = self._update_data(op_ids, oldest_opp)
|
||||
|
||||
#copy message into the first opportunity + merge attachement
|
||||
|
||||
for opp in tail_opportunities + [first_opportunity]:
|
||||
attach_ids = self.get_attachments(cr, uid, opp, context=context)
|
||||
self.set_attachements_res_id(cr, uid, first_opportunity.id, attach_ids)
|
||||
count = 1
|
||||
first_attachments = self.get_attachments(cr, uid, first_opportunity, context=context)
|
||||
for opp in tail_opportunities:
|
||||
attachments = self.get_attachments(cr, uid, opp, context=context)
|
||||
for first in first_attachments:
|
||||
for attachment in attachments:
|
||||
if attachment.name == first.name:
|
||||
values = dict(
|
||||
name = "%s (%s)" % (attachment.name, count,),
|
||||
res_id = first_opportunity.id,
|
||||
)
|
||||
attachment.write(values)
|
||||
count+=1
|
||||
|
||||
for history in opp.message_ids:
|
||||
message_obj.write(cr, uid, history.id, {'res_id': first_opportunity.id, 'name' : _("From %s : %s") % (opp.name, history.name) }, context=context)
|
||||
|
||||
|
@ -172,16 +174,14 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
subject = subject[0] + ", ".join(subject[1:])
|
||||
details = "\n\n".join(details)
|
||||
|
||||
opp_obj._history(cr, uid, [first_opportunity], subject, details=details)
|
||||
opp_obj.message_append(cr, uid, [first_opportunity], subject, body_text=details)
|
||||
#data.update({'message_ids' : [(6, 0 ,self._concat_o2m('message_ids', op_ids))]})
|
||||
opp_obj.write(cr, uid, [first_opportunity.id], data)
|
||||
opp_obj.write(cr, uid, [first_opportunity.id], data, context=context)
|
||||
unlink_ids = map(lambda x: x.id, tail_opportunities)
|
||||
opp_obj.unlink(cr, uid, unlink_ids, context=context)
|
||||
|
||||
models_data = self.pool.get('ir.model.data')
|
||||
|
||||
|
||||
|
||||
# Get Opportunity views
|
||||
opportunity_view_form = models_data._get_id(
|
||||
cr, uid, 'crm', 'crm_case_form_view_oppor')
|
||||
|
@ -216,7 +216,6 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
context['lead_ids'] = [op_ids[0].id]
|
||||
return self.merge(cr, uid, op_ids, context)
|
||||
|
||||
|
||||
_columns = {
|
||||
'opportunity_ids' : fields.many2many('crm.lead', 'merge_opportunity_rel', 'merge_id', 'opportunity_id', 'Opportunities', domain=[('type', '=', 'opportunity')]),
|
||||
}
|
||||
|
|
|
@ -1,303 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# 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 crm import crm
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
import base64
|
||||
import itertools
|
||||
import tools
|
||||
import re
|
||||
|
||||
|
||||
AVAILABLE_STATES = crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')]
|
||||
|
||||
|
||||
class crm_send_new_email_attachment(osv.osv_memory):
|
||||
_name = 'crm.send.mail.attachment'
|
||||
|
||||
_columns = {
|
||||
'binary' : fields.binary('Attachment', required=True),
|
||||
'name' : fields.char('Name', size=128, required=True),
|
||||
'wizard_id' : fields.many2one('crm.send.mail', 'Wizard', required=True),
|
||||
}
|
||||
|
||||
crm_send_new_email_attachment()
|
||||
|
||||
class crm_send_new_email(osv.osv_memory):
|
||||
""" Sends new email for the case"""
|
||||
_name = "crm.send.mail"
|
||||
_description = "Send new email"
|
||||
|
||||
_columns = {
|
||||
'email_to' : fields.char('To', size=512, required=True),
|
||||
'email_from' : fields.char('From', size=128, required=True),
|
||||
'reply_to' : fields.char('Reply To', size=128, required=True, help="Reply-to of the Sales team defined on this case"),
|
||||
'email_cc' : fields.char('CC', size=512, help="These addresses will receive a copy of this email. To modify the permanent CC list, edit the global CC field of this case"),
|
||||
'subject': fields.char('Subject', size=512, required=True),
|
||||
'body': fields.text('Message Body', required=True),
|
||||
'state': fields.selection(AVAILABLE_STATES, string='Set New State To', required=True),
|
||||
'attachment_ids' : fields.one2many('crm.send.mail.attachment', 'wizard_id', 'Attachment'),
|
||||
'html': fields.boolean('HTML formatting?', help="Select this if you want to send email with HTML formatting."),
|
||||
}
|
||||
|
||||
def action_mass_send(self, cr, uid, ids, context=None):
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
context.update({'mail' : 'new'})
|
||||
actives_ids = context.get('active_ids')
|
||||
model = context.get('active_model')
|
||||
case_pool = self.pool.get(model)
|
||||
for id in actives_ids:
|
||||
context.update({'active_id' : id})
|
||||
self.action_send(cr, uid, ids, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def action_send(self, cr, uid, ids, context=None):
|
||||
""" This sends an email to ALL the addresses of the selected partners.
|
||||
"""
|
||||
hist_obj = self.pool.get('mailgate.message')
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if not context.get('active_model'):
|
||||
raise osv.except_osv(_('Error'), _('Can not send mail!'))
|
||||
|
||||
model = context.get('active_model')
|
||||
case_pool = self.pool.get(model)
|
||||
res_id = context and context.get('active_id', False) or False
|
||||
|
||||
|
||||
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
attach = [
|
||||
(x.name, base64.decodestring(x.binary)) for x in obj.attachment_ids
|
||||
]
|
||||
|
||||
subtype = 'plain'
|
||||
message_id = None
|
||||
ref_id = None
|
||||
|
||||
case = case_pool.browse(cr, uid, res_id, context=context)
|
||||
if context.get('mail', 'new') == 'new':
|
||||
if case.message_ids:
|
||||
message_id = case.message_ids[0].message_id
|
||||
elif context.get('mail') == 'forward':
|
||||
# extract attachements from case and emails according to mode
|
||||
attachments = []
|
||||
attach_pool = self.pool.get('ir.attachment')
|
||||
direct_attachments = attach_pool.search(cr, uid, [('res_model', '=', 'crm.lead'), ('res_id', '=', res_id)], context=context)
|
||||
attachments += attach_pool.browse(cr, uid, direct_attachments, context=context)
|
||||
if obj.history in ['latest', 'whole'] and case.message_ids:
|
||||
msgs = case.message_ids
|
||||
if obj.history == 'latest':
|
||||
msgs = msgs[:1]
|
||||
attachments.extend(itertools.chain(*[m.attachment_ids for m in msgs]))
|
||||
attach_all = [(a.datas_fname or a.name, base64.decodestring(a.datas)) for a in attachments if a.datas]
|
||||
attach += attach_all
|
||||
|
||||
else:
|
||||
hist = hist_obj.browse(cr, uid, res_id, context=context)
|
||||
message_id = hist.message_id
|
||||
model = hist.model
|
||||
case_pool = self.pool.get(model)
|
||||
res_id = hist.res_id
|
||||
ref_id = hist.ref_id
|
||||
case = case_pool.browse(cr, uid, res_id, context=context)
|
||||
|
||||
if context.get('mass_mail'):
|
||||
email_temp = case.email_from and tools.ustr(case.email_from) or ''
|
||||
emails = re.findall(r'([^ ,<@]+@[^> ,]+)', email_temp)
|
||||
else:
|
||||
emails = re.findall(r'([^ ,<@]+@[^> ,]+)', obj.email_to or '')
|
||||
|
||||
email_cc = re.findall(r'([^ ,<@]+@[^> ,]+)', obj.email_cc or '')
|
||||
|
||||
emails = filter(None, emails)
|
||||
body = obj.body
|
||||
|
||||
body = body and tools.ustr(body) or ''
|
||||
email_from = getattr(obj, 'email_from', False)
|
||||
x_headers = {}
|
||||
if message_id:
|
||||
x_headers['References'] = "%s" % (message_id)
|
||||
|
||||
if obj.html:
|
||||
subtype = 'html'
|
||||
|
||||
flag = tools.email_send(
|
||||
email_from,
|
||||
emails,
|
||||
obj.subject,
|
||||
body,
|
||||
email_cc=email_cc,
|
||||
attach=attach,
|
||||
subtype=subtype,
|
||||
reply_to=obj.reply_to,
|
||||
openobject_id=str(case.id),
|
||||
x_headers=x_headers
|
||||
)
|
||||
|
||||
if not flag:
|
||||
raise osv.except_osv(_('Error!'), _('Unable to send mail. Please check SMTP is configured properly.'))
|
||||
|
||||
msg_dict = {'new': 'Send', 'reply': 'Reply', 'forward': 'Forward'}
|
||||
case_pool.history(cr, uid, [case], _(msg_dict[context.get('mail', 'new')]), history=True, \
|
||||
email=obj.email_to, details=body, \
|
||||
subject=obj.subject, email_from=email_from, \
|
||||
email_cc=', '.join(email_cc), message_id=message_id, \
|
||||
references=ref_id or message_id, attach=attach)
|
||||
if obj.state == 'unchanged':
|
||||
pass
|
||||
elif obj.state == 'done':
|
||||
case_pool.case_close(cr, uid, [case.id])
|
||||
elif obj.state == 'draft':
|
||||
case_pool.case_reset(cr, uid, [case.id])
|
||||
elif obj.state in ['cancel', 'open', 'pending']:
|
||||
act = 'case_' + obj.state
|
||||
getattr(case_pool, act)(cr, uid, [case.id])
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if not context.get('active_model'):
|
||||
raise osv.except_osv(_('Error'), _('Can not send mail!'))
|
||||
|
||||
res = super(crm_send_new_email, self).default_get(cr, uid, fields, context=context)
|
||||
|
||||
if context.get('mail') == 'reply':
|
||||
res.update(self.get_reply_defaults(cr, uid, fields, context=context))
|
||||
return res
|
||||
|
||||
model = context.get('active_model')
|
||||
mod_obj = self.pool.get(model)
|
||||
res_id = context and context.get('active_ids', []) or []
|
||||
|
||||
user_obj = self.pool.get('res.users')
|
||||
user_mail_from = user_obj._get_email_from(cr, uid, [uid], context=context)[uid]
|
||||
for case in mod_obj.browse(cr, uid, res_id, context=context):
|
||||
if 'email_to' in fields:
|
||||
res.update({'email_to': case.email_from and tools.ustr(case.email_from) or ''})
|
||||
if context.get('mass_mail'):
|
||||
res.update({'email_to': ''})
|
||||
if 'email_from' in fields:
|
||||
res.update({'email_from': user_mail_from and tools.ustr(user_mail_from) or ''})
|
||||
if 'reply_to' in fields:
|
||||
if hasattr(case, 'section_id'):
|
||||
res.update({'reply_to': case.section_id and case.section_id.reply_to or False})
|
||||
if 'subject' in fields:
|
||||
res.update({'subject': tools.ustr(context.get('subject', case.name) or '')})
|
||||
if context.get('mass_mail'):
|
||||
res.update({'subject': ''})
|
||||
if 'email_cc' in fields:
|
||||
res.update({'email_cc': tools.ustr(case.email_cc or '')})
|
||||
if context.get('mass_mail'):
|
||||
res.update({'email_cc': ''})
|
||||
if 'body' in fields:
|
||||
res.update({'body': u'\n'+(tools.ustr(case.user_id.signature or ''))})
|
||||
if 'state' in fields:
|
||||
res.update({'state': u'pending'})
|
||||
|
||||
return res
|
||||
|
||||
def get_reply_defaults(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values for reply mail
|
||||
"""
|
||||
hist_obj = self.pool.get('mailgate.message')
|
||||
res_ids = context and context.get('active_ids', []) or []
|
||||
|
||||
user_obj = self.pool.get('res.users')
|
||||
user_mail_from = user_obj._get_email_from(cr, uid, [uid], context=context)[uid]
|
||||
|
||||
include_original = context and context.get('include_original', False) or False
|
||||
res = {}
|
||||
for hist in hist_obj.browse(cr, uid, res_ids, context=context):
|
||||
model = hist.model
|
||||
|
||||
# In the case where the crm.case does not exist in the database
|
||||
if not model:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
model_pool = self.pool.get(model)
|
||||
res_id = hist.res_id
|
||||
case = model_pool.browse(cr, uid, res_id)
|
||||
if 'email_to' in fields:
|
||||
res.update({'email_to': case.email_from and tools.ustr(case.email_from) or False})
|
||||
if 'email_from' in fields:
|
||||
res.update({'email_from': user_mail_from and tools.ustr(user_mail_from) or False})
|
||||
|
||||
signature = u'\n' + (tools.ustr(case.user_id.signature or '')) + u'\n'
|
||||
original = [signature]
|
||||
|
||||
if include_original == True and 'body' in fields:
|
||||
header = u'-------- Original Message --------'
|
||||
sender = u'From: %s' %(tools.ustr(hist.email_from or ''))
|
||||
to = u'To: %s' % (tools.ustr(hist.email_to or ''))
|
||||
sentdate = u'Date: %s' % (tools.ustr(hist.date))
|
||||
desc = u'\n%s'%(tools.ustr(hist.description))
|
||||
|
||||
original = [signature, header, sender, to, sentdate, desc]
|
||||
|
||||
res['body']= u'\n' + u'\n'.join(original)
|
||||
|
||||
if 'subject' in fields:
|
||||
res.update({u'subject': u'Re: %s' %(tools.ustr(hist.name or ''))})
|
||||
if 'email_cc' in fields:
|
||||
email_cc = (case.email_cc and tools.ustr(case.email_cc) + ', ' or '') + (hist.email_cc or '')
|
||||
res.update({'email_cc': email_cc})
|
||||
if 'reply_to' in fields:
|
||||
if hasattr(case, 'section_id'):
|
||||
res.update({'reply_to': case.section_id.reply_to or ''})
|
||||
if 'state' in fields:
|
||||
res['state'] = u'pending'
|
||||
return res
|
||||
|
||||
def view_init(self, cr, uid, fields_list, context=None):
|
||||
"""
|
||||
This function checks for precondition before wizard executes
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param fields: List of fields for default value
|
||||
@param context: A standard dictionary for contextual values
|
||||
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if not context.get('active_model'):
|
||||
raise osv.except_osv(_('Error'), _('Can not send mail!'))
|
||||
return True
|
||||
|
||||
crm_send_new_email()
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Send New Mail view -->
|
||||
|
||||
<record model="ir.ui.view" id="crm_send_new_mail_view">
|
||||
<field name="name">crm.new.send.mail.form</field>
|
||||
<field name="model">crm.send.mail</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Send Mail" col="4">
|
||||
<group colspan="4" col="2">
|
||||
<field name="email_from"/>
|
||||
<field name="reply_to"/>
|
||||
<field name="email_to" />
|
||||
<field name="email_cc"/>
|
||||
<field name="subject"/>
|
||||
<field name="html"/>
|
||||
</group>
|
||||
<notebook colspan="6">
|
||||
<page string="Message">
|
||||
<field name="body" nolabel="1" colspan="4" default_focus="1"/>
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1">
|
||||
<form string="Attachment">
|
||||
<field name="binary" filename="name" />
|
||||
<field name="name" />
|
||||
</form>
|
||||
<tree string="Attachments">
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<separator string="" colspan="6"/>
|
||||
<group colspan="6" col="4" >
|
||||
<field name="state" />
|
||||
<button string="_Cancel" icon="gtk-close" special="cancel" />
|
||||
<button name="action_send" type="object" string="_Send" icon="gtk-go-forward" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crm_send_new_mass_mail_view">
|
||||
<field name="name">crm.new.send.mass.mail.form</field>
|
||||
<field name="model">crm.send.mail</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Send Mail" col="4">
|
||||
<group colspan="4" col="2">
|
||||
<field name="email_from"/>
|
||||
<field name="reply_to"/>
|
||||
<field name="email_cc"/>
|
||||
<field name="subject" />
|
||||
<field name="html"/>
|
||||
</group>
|
||||
<notebook colspan="6">
|
||||
<page string="Message">
|
||||
<field name="body" nolabel="1" colspan="4" default_focus="1"/>
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1">
|
||||
<form string="Attachment">
|
||||
<field name="binary" filename="name" />
|
||||
<field name="name" />
|
||||
</form>
|
||||
<tree string="Attachments">
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<separator string="" colspan="6"/>
|
||||
<group colspan="6" col="4" >
|
||||
<field name="state" />
|
||||
<button string="_Cancel" icon="gtk-cancel" special="cancel" />
|
||||
<button name="action_mass_send" type="object" string="_Send to All" icon="gtk-go-forward" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Send New Mail action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_crm_send_mail">
|
||||
<field name="name">Send Mail</field>
|
||||
<field name="res_model">crm.send.mail</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="crm_send_new_mail_view"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
|
||||
<act_window id="action_crm_send_mass_mail"
|
||||
multi="True"
|
||||
key2="client_action_multi" name="Send emails"
|
||||
res_model="crm.send.mail" src_model="crm.lead"
|
||||
view_mode="form" target="new" view_type="form"
|
||||
context="{'mass_mail' : True}"
|
||||
view_id="crm_send_new_mass_mail_view"/>
|
||||
|
||||
<!-- Reply to Mail view -->
|
||||
|
||||
<record model="ir.ui.view" id="crm_reply_mail_view">
|
||||
<field name="name">crm.mail.reply.form</field>
|
||||
<field name="model">crm.send.mail</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reply to last Mail" col="2">
|
||||
<field name="email_from" />
|
||||
<field name="email_to" />
|
||||
<field name="email_cc" />
|
||||
<field name="subject" />
|
||||
<field name="attachment_ids" colspan="4" nolabel="1">
|
||||
<form string="Attachment">
|
||||
<field name="binary" filename="name" />
|
||||
<field name="name" />
|
||||
</form>
|
||||
<tree string="Attachments">
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
<separator string="" colspan="4"/>
|
||||
<field name="body" nolabel="1" colspan="4"/>
|
||||
<separator string=" " colspan="4"/>
|
||||
<group colspan="4" col="3" >
|
||||
<label string=" " />
|
||||
<button string="_Cancel" icon="gtk-close" special="cancel" />
|
||||
<button name="action_send" type="object" string="_Send Reply" icon="gtk-go-forward" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Reply to Mail action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_crm_reply_mail">
|
||||
<field name="name">Reply to last Mail</field>
|
||||
<field name="res_model">crm.send.mail</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="crm_reply_mail_view"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,63 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2010-Today 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
import tools
|
||||
|
||||
SUPPORTED_MODELS = ['crm.lead',]
|
||||
|
||||
class mail_compose_message(osv.osv_memory):
|
||||
_inherit = 'mail.compose.message'
|
||||
|
||||
def get_value(self, cr, uid, model, res_id, context=None):
|
||||
"""Returns a defaults-like dict with initial values for the composition
|
||||
wizard when sending an email related to the document record identified
|
||||
by ``model`` and ``res_id``.
|
||||
|
||||
Overrides the default implementation to provide more default field values
|
||||
related to the corresponding CRM case.
|
||||
|
||||
:param str model: model name of the document record this mail is related to.
|
||||
:param int res_id: id of the document record this mail is related to.
|
||||
:param dict context: several context values will modify the behavior
|
||||
of the wizard, cfr. the class description.
|
||||
"""
|
||||
result = super(mail_compose_message, self).get_value(cr, uid, model, res_id, context=context)
|
||||
if model in SUPPORTED_MODELS and res_id:
|
||||
model_obj = self.pool.get(model)
|
||||
data = model_obj.browse(cr, uid , res_id, context)
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
result.update({
|
||||
'subject' : data.name or False,
|
||||
'email_to' : data.email_from or False,
|
||||
'email_from' : user.user_email or tools.config.get('email_from', False),
|
||||
'body_text' : '\n' + tools.ustr(user.signature),
|
||||
'email_cc' : tools.ustr(data.email_cc or ''),
|
||||
'model': model,
|
||||
'res_id': res_id,
|
||||
'subtype': 'plain',
|
||||
})
|
||||
if hasattr(data, 'section_id'):
|
||||
result.update({'reply_to' : data.section_id and data.section_id.reply_to or False})
|
||||
return result
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -32,7 +32,7 @@ def _open_history_event(self, cr, uid, data, context=None):
|
|||
if id2:
|
||||
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
|
||||
res = ''
|
||||
if data.get('model',False) and data.get('ids',False):
|
||||
if data.get('model') and data.get('ids'):
|
||||
model_obj = pooler.get_pool(cr.dbname).get(data['model'])
|
||||
res = model_obj.browse(cr, uid, data['ids'], context=context)
|
||||
if len(res):
|
||||
|
|
|
@ -22,10 +22,12 @@
|
|||
from osv import fields, osv
|
||||
from crm import crm
|
||||
import time
|
||||
from crm import wizard
|
||||
import binascii
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
wizard.mail_compose_message.SUPPORTED_MODELS.append('crm.claim')
|
||||
CRM_CLAIM_PENDING_STATES = (
|
||||
crm.AVAILABLE_STATES[2][0], # Cancelled
|
||||
crm.AVAILABLE_STATES[3][0], # Done
|
||||
|
@ -40,69 +42,69 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
_name = "crm.claim"
|
||||
_description = "Claim"
|
||||
_order = "priority,date desc"
|
||||
_inherit = ['mailgate.thread']
|
||||
_inherit = ['mail.thread']
|
||||
_columns = {
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Claim Subject', size=128, required=True),
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Claim Subject', size=128, required=True),
|
||||
'action_next': fields.char('Next Action', size=200),
|
||||
'date_action_next': fields.datetime('Next Action Date'),
|
||||
'description': fields.text('Description'),
|
||||
'resolution': fields.text('Resolution'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Claim Date'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'description': fields.text('Description'),
|
||||
'resolution': fields.text('Resolution'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Claim Date'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.claim')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
('object_id.model', '=', 'crm.claim')]"),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'user_fault': fields.char('Trouble Responsible', size=64),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'user_fault': fields.char('Trouble Responsible', size=64),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
|
||||
select=True, help="Sales team to which Case belongs to."\
|
||||
"Define Responsible user and Email account for"\
|
||||
" mail gateway."),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
" mail gateway."),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
|
||||
# domain="[('partner_id','=',partner_id)]"
|
||||
),
|
||||
'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
),
|
||||
'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids','=',section_id)]"),
|
||||
'cause': fields.text('Root Cause'),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
'cause': fields.text('Root Cause'),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from':crm.crm_case. _get_default_email,
|
||||
'state': lambda *a: 'draft',
|
||||
'section_id': crm.crm_case._get_section,
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from':crm.crm_case. _get_default_email,
|
||||
'state': lambda *a: 'draft',
|
||||
'section_id':crm.crm_case. _get_section,
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
}
|
||||
|
||||
|
||||
def onchange_partner_id(self, cr, uid, ids, part, email=False):
|
||||
"""This function returns value of partner address based on partner
|
||||
@param part: Partner's id
|
||||
@email: Partner's email ID
|
||||
:param part: Partner's id
|
||||
:param email: ignored
|
||||
"""
|
||||
if not part:
|
||||
return {'value': {'partner_address_id': False,
|
||||
'email_from': False,
|
||||
'email_from': False,
|
||||
'partner_phone': False,
|
||||
'partner_mobile': False
|
||||
}}
|
||||
|
@ -113,8 +115,8 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
|
||||
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
|
||||
"""This function returns value of partner email based on Partner Address
|
||||
@param add: Id of Partner's address
|
||||
@email: Partner's email ID
|
||||
:param part: Partner's id
|
||||
:param email: ignored
|
||||
"""
|
||||
if not add:
|
||||
return {'value': {'email_from': False}}
|
||||
|
@ -122,6 +124,7 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
return {'value': {'email_from': address.email, 'partner_phone': address.phone, 'partner_mobile': address.mobile}}
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
"""Opens Claim"""
|
||||
for l in self.browse(cr, uid, ids):
|
||||
# When coming from draft override date and stage otherwise just set state
|
||||
if l.state == 'draft':
|
||||
|
@ -135,16 +138,13 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
res = super(crm_claim, self).case_open(cr, uid, ids, *args)
|
||||
return res
|
||||
|
||||
def message_new(self, cr, uid, msg, context=None):
|
||||
""" Automatically calls when new email message arrives
|
||||
"""
|
||||
mailgate_pool = self.pool.get('email.server.tools')
|
||||
|
||||
subject = msg.get('subject') or _("No Subject")
|
||||
body = msg.get('body')
|
||||
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
||||
"""Automatically called when new email message arrives"""
|
||||
res_id = super(crm_claim,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
|
||||
subject = msg.get('subject')
|
||||
body = msg.get('body_text')
|
||||
msg_from = msg.get('from')
|
||||
priority = msg.get('priority')
|
||||
|
||||
vals = {
|
||||
'name': subject,
|
||||
'email_from': msg_from,
|
||||
|
@ -152,35 +152,18 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
'description': body,
|
||||
'user_id': False,
|
||||
}
|
||||
if msg.get('priority', False):
|
||||
if priority:
|
||||
vals['priority'] = priority
|
||||
vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
|
||||
self.write(cr, uid, [res_id], vals, context=context)
|
||||
return res_id
|
||||
|
||||
res = mailgate_pool.get_partner(cr, uid, msg.get('from') or msg.get_unixfrom())
|
||||
if res:
|
||||
vals.update(res)
|
||||
|
||||
res = self.create(cr, uid, vals, context)
|
||||
attachents = msg.get('attachments', [])
|
||||
for attactment in attachents or []:
|
||||
data_attach = {
|
||||
'name': attactment,
|
||||
'datas':binascii.b2a_base64(str(attachents.get(attactment))),
|
||||
'datas_fname': attactment,
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self._name,
|
||||
'res_id': res,
|
||||
}
|
||||
self.pool.get('ir.attachment').create(cr, uid, data_attach)
|
||||
|
||||
return res
|
||||
|
||||
def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None):
|
||||
"""
|
||||
@param ids: List of update mail’s IDs
|
||||
"""
|
||||
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
ids = [ids]
|
||||
|
||||
res_id = super(crm_claim,self).message_update(cr, uid, ids, msg, context=context)
|
||||
|
||||
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
|
||||
vals['priority'] = msg.get('priority')
|
||||
|
||||
|
@ -190,7 +173,7 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
'probability':'probability'
|
||||
}
|
||||
vls = {}
|
||||
for line in msg['body'].split('\n'):
|
||||
for line in msg['body_text'].split('\n'):
|
||||
line = line.strip()
|
||||
res = tools.misc.command_re.match(line)
|
||||
if res and maps.get(res.group(1).lower()):
|
||||
|
@ -208,19 +191,10 @@ class crm_claim(crm.crm_case, osv.osv):
|
|||
res = self.write(cr, uid, [case.id], values, context=context)
|
||||
return res
|
||||
|
||||
def msg_send(self, cr, uid, id, *args, **argv):
|
||||
""" Send The Message
|
||||
@param ids: List of email’s IDs
|
||||
"""
|
||||
return True
|
||||
|
||||
crm_claim()
|
||||
|
||||
class res_partner(osv.osv):
|
||||
_inherit = 'res.partner'
|
||||
_columns = {
|
||||
'claims_ids': fields.one2many('crm.claim', 'partner_id', 'Claims'),
|
||||
}
|
||||
res_partner()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -70,15 +70,10 @@
|
|||
<group>
|
||||
<field name="name" />
|
||||
<field name="date"/>
|
||||
|
||||
|
||||
</group>
|
||||
|
||||
<group colspan="4" col="6">
|
||||
|
||||
<field name="user_id"/>
|
||||
<field name="section_id" widget="selection" />
|
||||
|
||||
<group colspan="2" col="4">
|
||||
<field name="stage_id" domain="[('section_ids','=',section_id)]"/>
|
||||
<button name="stage_previous" string="" type="object" icon="gtk-go-back" />
|
||||
|
@ -159,12 +154,12 @@
|
|||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<button
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.claim', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" attrs="{'invisible': [('history', '!=', True)]}" />
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply'}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="Communication & History">
|
||||
<group col="4" colspan="4">
|
||||
|
@ -172,20 +167,18 @@
|
|||
<field name="date"/>
|
||||
<field name="email_to" widget="char" size="512"/>
|
||||
<field name="email_cc" widget="char" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" size="512"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<field name="subject" colspan="4" widget="char" size="512"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<field name="description" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.claim', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('history', '=', True)]}">
|
||||
<group attrs="{'invisible': [('email_from', '!=', False)]}">
|
||||
<field name="display_text" colspan="4" nolabel="1" height="250"/>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -199,10 +192,9 @@
|
|||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.claim'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
|
|
|
@ -60,7 +60,7 @@ class crm_claim_report(osv.osv):
|
|||
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
|
||||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
'create_date': fields.datetime('Create Date', readonly=True, select=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True,domain="[('section_ids','=',section_id)]"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category',\
|
||||
|
@ -71,8 +71,8 @@ class crm_claim_report(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
'priority': fields.selection(AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'),
|
||||
'date_closed': fields.date('Close Date', readonly=True, select=True),
|
||||
'date_deadline': fields.date('Deadline', readonly=True, select=True),
|
||||
'date_closed': fields.date('Close Date', readonly=True, select=True),
|
||||
'date_deadline': fields.date('Deadline', readonly=True, select=True),
|
||||
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
|
||||
'email': fields.integer('# Emails', size=128, readonly=True),
|
||||
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg")
|
||||
|
@ -106,7 +106,7 @@ class crm_claim_report(osv.osv):
|
|||
c.type_action as type_action,
|
||||
date_trunc('day',c.create_date) as create_date,
|
||||
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close,
|
||||
(SELECT count(id) FROM mailgate_message WHERE model='crm.claim' AND res_id=c.id AND history=True) AS email,
|
||||
(SELECT count(id) FROM mail_message WHERE model='crm.claim' AND res_id=c.id AND email_from IS NOT NULL) AS email,
|
||||
(SELECT avg(probability) FROM crm_case_stage WHERE id=c.stage_id) AS probability,
|
||||
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected
|
||||
from
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
from osv import fields, osv
|
||||
from crm import crm
|
||||
from crm import wizard
|
||||
|
||||
wizard.mail_compose_message.SUPPORTED_MODELS.append('crm.fundraising')
|
||||
|
||||
class crm_fundraising(crm.crm_case, osv.osv):
|
||||
""" Fund Raising Cases """
|
||||
|
@ -28,67 +31,84 @@ class crm_fundraising(crm.crm_case, osv.osv):
|
|||
_name = "crm.fundraising"
|
||||
_description = "Fund Raising"
|
||||
_order = "id desc"
|
||||
_inherit = ['mailgate.thread']
|
||||
_inherit = ['mail.thread']
|
||||
_columns = {
|
||||
'id': fields.integer('ID'),
|
||||
'id': fields.integer('ID'),
|
||||
'name': fields.char('Name', size=128, required=True),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'description': fields.text('Description'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'description': fields.text('Description'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
|
||||
select=True, help='Sales team to which Case belongs to. Define Responsible user and Email account for mail gateway.'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
select=True, help='Sales team to which Case belongs to. Define Responsible user and Email account for mail gateway.'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'email_cc': fields.text('Watchers Emails', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'email_cc': fields.text('Watchers Emails', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.fundraising')]"),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_name2': fields.char('Employee Email', size=64),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
('object_id.model', '=', 'crm.fundraising')]"),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
'partner_name': fields.char("Employee's Name", size=64),
|
||||
'partner_name2': fields.char('Employee Email', size=64),
|
||||
'partner_phone': fields.char('Phone', size=32),
|
||||
'partner_mobile': fields.char('Mobile', size=32),
|
||||
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
|
||||
domain="[('section_id','=',section_id)]"),
|
||||
'duration': fields.float('Duration'),
|
||||
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
domain="[('section_id','=',section_id)]"),
|
||||
'duration': fields.float('Duration'),
|
||||
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
}
|
||||
|
||||
|
||||
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
||||
"""Automatically called when new email message arrives"""
|
||||
res_id = super(crm_fundraising,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
|
||||
vals = {
|
||||
'name': msg.get('subject'),
|
||||
'email_from': msg.get('from'),
|
||||
'email_cc': msg.get('cc'),
|
||||
'description': msg.get('body_text'),
|
||||
}
|
||||
priority = msg.get('priority')
|
||||
if priority:
|
||||
vals['priority'] = priority
|
||||
vals.update(self.message_partner_by_email(cr, uid, msg.get('from')))
|
||||
self.write(cr, uid, [res_id], vals, context=context)
|
||||
return res_id
|
||||
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from': crm.crm_case. _get_default_email,
|
||||
'state': lambda *a: 'draft',
|
||||
'section_id': crm.crm_case. _get_section,
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'probability': lambda *a:0.0,
|
||||
'planned_cost': lambda *a:0.0,
|
||||
'planned_revenue': lambda *a:0.0,
|
||||
}
|
||||
'active': 1,
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from': crm.crm_case. _get_default_email,
|
||||
'state': 'draft',
|
||||
'section_id': crm.crm_case. _get_section,
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
||||
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'probability': 0.0,
|
||||
'planned_cost': 0.0,
|
||||
'planned_revenue': 0.0,
|
||||
}
|
||||
|
||||
crm_fundraising()
|
||||
|
||||
|
|
|
@ -136,15 +136,15 @@
|
|||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.fundraising', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
|
@ -152,20 +152,18 @@
|
|||
<field name="date"/>
|
||||
<field name="email_to" widget="char" size="512"/>
|
||||
<field name="email_cc" widget="char" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" size="512"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<field name="subject" colspan="4" widget="char" size="512"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<field name="description" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.fundraising', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('history', '=', True)]}">
|
||||
<group attrs="{'invisible': [('email_from', '!=', False)]}">
|
||||
<field name="display_text" colspan="4" nolabel="1" height="250"/>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -179,10 +177,9 @@
|
|||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.fundraising'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group col="2" colspan="2">
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
from crm import crm
|
||||
from osv import fields, osv
|
||||
import time
|
||||
import binascii
|
||||
from crm import wizard
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
|
@ -32,121 +32,92 @@ CRM_HELPDESK_STATES = (
|
|||
crm.AVAILABLE_STATES[4][0], # Pending
|
||||
)
|
||||
|
||||
wizard.mail_compose_message.SUPPORTED_MODELS.append('crm.helpdesk')
|
||||
|
||||
class crm_helpdesk(crm.crm_case, osv.osv):
|
||||
""" Helpdesk Cases """
|
||||
|
||||
_name = "crm.helpdesk"
|
||||
_description = "Helpdesk"
|
||||
_order = "id desc"
|
||||
_inherit = ['mailgate.thread']
|
||||
_inherit = ['mail.thread']
|
||||
_columns = {
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Name', size=128, required=True),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'description': fields.text('Description'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Name', size=128, required=True),
|
||||
'active': fields.boolean('Active', required=False),
|
||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||
'description': fields.text('Description'),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Update Date' , readonly=True),
|
||||
'date_deadline': fields.date('Deadline'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
|
||||
select=True, help='Sales team to which Case belongs to.\
|
||||
Define Responsible user and Email account for mail gateway.'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
Define Responsible user and Email account for mail gateway.'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'email_cc': fields.text('Watchers Emails', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date': fields.datetime('Date'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
domain="[('partner_id','=',partner_id)]"),
|
||||
'email_cc': fields.text('Watchers Emails', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
|
||||
'email_from': fields.char('Email', size=128, help="These people will receive email."),
|
||||
'date': fields.datetime('Date'),
|
||||
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel."),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
|
||||
'probability': fields.float('Probability (%)'),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
\nWhen the case is over, the state is set to \'Done\'.\
|
||||
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from': crm.crm_case. _get_default_email,
|
||||
'state': lambda *a: 'draft',
|
||||
'active': lambda *a: 1,
|
||||
'user_id': crm.crm_case._get_default_user,
|
||||
'partner_id': crm.crm_case._get_default_partner,
|
||||
'partner_address_id': crm.crm_case._get_default_partner_address,
|
||||
'email_from': crm.crm_case. _get_default_email,
|
||||
'state': lambda *a: 'draft',
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'section_id': crm.crm_case. _get_section,
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
'section_id': crm.crm_case. _get_section,
|
||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||
}
|
||||
|
||||
def message_new(self, cr, uid, msg, context=None):
|
||||
"""
|
||||
Automatically calls when new email message arrives
|
||||
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks
|
||||
"""
|
||||
mailgate_pool = self.pool.get('email.server.tools')
|
||||
|
||||
subject = msg.get('subject') or _("No Subject")
|
||||
body = msg.get('body')
|
||||
msg_from = msg.get('from')
|
||||
priority = msg.get('priority')
|
||||
|
||||
def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
|
||||
"""Automatically called when new email message arrives"""
|
||||
res_id = super(crm_helpdesk,self).message_new(cr, uid, msg_dict, custom_values=custom_values, context=context)
|
||||
subject = msg_dict.get('subject') or _("No Subject")
|
||||
body = msg_dict.get('body_text')
|
||||
msg_from = msg_dict.get('from')
|
||||
vals = {
|
||||
'name': subject,
|
||||
'email_from': msg_from,
|
||||
'email_cc': msg.get('cc'),
|
||||
'email_cc': msg_dict.get('cc'),
|
||||
'description': body,
|
||||
'user_id': False,
|
||||
}
|
||||
if msg.get('priority', False):
|
||||
vals['priority'] = priority
|
||||
vals.update(self.message_partner_by_email(cr, uid, msg_from))
|
||||
self.write(cr, uid, [res_id], vals, context)
|
||||
return res_id
|
||||
|
||||
res = mailgate_pool.get_partner(cr, uid, msg.get('from') or msg.get_unixfrom())
|
||||
if res:
|
||||
vals.update(res)
|
||||
|
||||
res = self.create(cr, uid, vals, context)
|
||||
attachents = msg.get('attachments', [])
|
||||
for attactment in attachents or []:
|
||||
data_attach = {
|
||||
'name': attactment,
|
||||
'datas':binascii.b2a_base64(str(attachents.get(attactment))),
|
||||
'datas_fname': attactment,
|
||||
'description': 'Mail attachment',
|
||||
'res_model': self._name,
|
||||
'res_id': res,
|
||||
}
|
||||
self.pool.get('ir.attachment').create(cr, uid, data_attach)
|
||||
|
||||
return res
|
||||
|
||||
def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None):
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of update mail’s IDs
|
||||
"""
|
||||
def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
ids = [ids]
|
||||
|
||||
super(crm_helpdesk,self).message_update(cr, uid, ids, msg, context=context)
|
||||
|
||||
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
|
||||
vals['priority'] = msg.get('priority')
|
||||
|
||||
|
@ -156,7 +127,7 @@ class crm_helpdesk(crm.crm_case, osv.osv):
|
|||
'probability':'probability'
|
||||
}
|
||||
vls = {}
|
||||
for line in msg['body'].split('\n'):
|
||||
for line in msg['body_text'].split('\n'):
|
||||
line = line.strip()
|
||||
res = tools.misc.command_re.match(line)
|
||||
if res and maps.get(res.group(1).lower()):
|
||||
|
@ -174,19 +145,5 @@ class crm_helpdesk(crm.crm_case, osv.osv):
|
|||
res = self.write(cr, uid, [case.id], values, context=context)
|
||||
return res
|
||||
|
||||
def msg_send(self, cr, uid, id, *args, **argv):
|
||||
|
||||
""" Send The Message
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of email’s IDs
|
||||
@param *args: Return Tuple Value
|
||||
@param **args: Return Dictionary of Keyword Value
|
||||
"""
|
||||
return True
|
||||
|
||||
crm_helpdesk()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -99,12 +99,12 @@
|
|||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.helpdesk', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
|
@ -112,20 +112,18 @@
|
|||
<field name="date"/>
|
||||
<field name="email_to" widget="char" size="512"/>
|
||||
<field name="email_cc" widget="char" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" size="512"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<field name="subject" colspan="4" widget="char" size="512"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<field name="description" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'crm.helpdesk', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('history', '=', True)]}">
|
||||
<group attrs="{'invisible': [('email_from', '!=', False)]}">
|
||||
<field name="display_text" colspan="4" nolabel="1" height="250"/>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -139,10 +137,9 @@
|
|||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'crm.helpdesk'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group colspan="2" col="2">
|
||||
|
|
|
@ -56,7 +56,7 @@ class crm_helpdesk_report(osv.osv):
|
|||
'date_deadline': fields.date('Deadline', select=True),
|
||||
'priority': fields.selection([('5', 'Lowest'), ('4', 'Low'), \
|
||||
('3', 'Normal'), ('2', 'High'), ('1', 'Highest')], 'Priority'),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel'),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel'),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
|
@ -97,7 +97,7 @@ class crm_helpdesk_report(osv.osv):
|
|||
c.planned_cost,
|
||||
count(*) as nbr,
|
||||
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
|
||||
(SELECT count(id) FROM mailgate_message WHERE model='crm.helpdesk' AND res_id=c.id AND history=True) AS email,
|
||||
(SELECT count(id) FROM mail_message WHERE model='crm.helpdesk' AND res_id=c.id AND email_from IS NOT NULL) AS email,
|
||||
abs(avg(extract('epoch' from (c.date_deadline - c.date_closed)))/(3600*24)) as delay_expected
|
||||
from
|
||||
crm_helpdesk c
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<filter string="Referred Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_assigned_id'}"/>
|
||||
</filter>
|
||||
|
||||
<field name="section_id" position="after">
|
||||
<field name="partner_id" position="after">
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_assigned_id"/>
|
||||
</field>
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
-
|
||||
In order to test Forward Partner functionality, I create an opportunity and forward it to partner.
|
||||
-
|
||||
-
|
||||
I assign an email address to Administrator.
|
||||
-
|
||||
-
|
||||
!record {model: res.users, id: base.user_root}:
|
||||
user_email: admin@openerp.com
|
||||
-
|
||||
-
|
||||
I create some partner grades.
|
||||
-
|
||||
I create a grade 'First'.
|
||||
-
|
||||
-
|
||||
!record {model: res.partner.grade, id: res_partner_grade_first0}:
|
||||
name: First
|
||||
sequence: 1
|
||||
-
|
||||
-
|
||||
I create another grade 'Second'.
|
||||
-
|
||||
-
|
||||
!record {model: res.partner.grade, id: res_partner_grade_second0}:
|
||||
name: Second
|
||||
sequence: 2
|
||||
-
|
||||
-
|
||||
I create one more grade 'Third'.
|
||||
-
|
||||
-
|
||||
!record {model: res.partner.grade, id: res_partner_grade_third0}:
|
||||
name: Third
|
||||
sequence: 3
|
||||
-
|
||||
-
|
||||
I assign grade 'First' to the partner 'Axelor'.
|
||||
-
|
||||
-
|
||||
!record {model: res.partner, id: base.res_partner_desertic_hispafuentes}:
|
||||
grade_id: res_partner_grade_first0
|
||||
-
|
||||
I assgin a reply-to email address to Sales Team.
|
||||
-
|
||||
-
|
||||
!record {model: crm.case.section, id: crm.section_sales_department}:
|
||||
reply_to: sales_openerp@openerp.com
|
||||
-
|
||||
-
|
||||
I create an opportunity 'Questionnaire on OpenERP'.
|
||||
-
|
||||
-
|
||||
!record {model: crm.lead, id: crm_lead_questionnaireonopenerp0}:
|
||||
categ_id: crm.categ_oppor7
|
||||
section_id: crm.section_sales_department
|
||||
|
@ -62,7 +62,7 @@
|
|||
!python {model: crm.lead.forward.to.partner}: |
|
||||
from tools import config
|
||||
vals = {
|
||||
'name': 'email',
|
||||
'subject': 'email',
|
||||
'email_to': 'info@axelor.com',
|
||||
'email_from': 'Administrator <admin@openerp.com>',
|
||||
'reply_to': 'sales_openerp@openerp.com'
|
||||
|
|
|
@ -28,10 +28,10 @@ from tools.translate import _
|
|||
class crm_lead_forward_to_partner(osv.osv_memory):
|
||||
"""Forwards lead history"""
|
||||
_name = 'crm.lead.forward.to.partner'
|
||||
_inherit = "crm.send.mail"
|
||||
_inherit = "mail.compose.message"
|
||||
|
||||
_columns = {
|
||||
'name': fields.selection([('user', 'User'), ('partner', 'Partner'), \
|
||||
'send_to': fields.selection([('user', 'User'), ('partner', 'Partner'), \
|
||||
('email', 'Email Address')], 'Send to', required=True),
|
||||
'user_id': fields.many2one('res.users', "User"),
|
||||
'partner_id' : fields.many2one('res.partner', 'Partner'),
|
||||
|
@ -40,7 +40,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
}
|
||||
|
||||
_defaults = {
|
||||
'name' : 'email',
|
||||
'send_to' : 'email',
|
||||
'history': 'latest',
|
||||
'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid],
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
@param hist_id: Id of latest history
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
log_pool = self.pool.get('mailgate.message')
|
||||
log_pool = self.pool.get('mail.message')
|
||||
hist = log_pool.browse(cr, uid, hist_id, context=context)
|
||||
header = '-------- Original Message --------'
|
||||
sender = 'From: %s' %(hist.email_from or '')
|
||||
to = 'To: %s' % (hist.email_to or '')
|
||||
sentdate = 'Date: %s' % (hist.date or '')
|
||||
desc = '\n%s'%(hist.description)
|
||||
desc = '\n%s'%(hist.body_text)
|
||||
original = [header, sender, to, sentdate, desc]
|
||||
original = '\n'.join(original)
|
||||
return original
|
||||
|
@ -109,7 +109,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
res_id = context.get('active_id')
|
||||
msg_val = self._get_case_history(cr, uid, history_type, res_id, context=context)
|
||||
if msg_val:
|
||||
res = {'value': {'body' : '\n\n' + msg_val}}
|
||||
res = {'value': {'body_text' : '\n\n' + msg_val}}
|
||||
return res
|
||||
|
||||
def _get_case_history(self, cr, uid, history_type, res_id, context=None):
|
||||
|
@ -125,12 +125,12 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
|
||||
elif history_type == 'whole':
|
||||
log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
|
||||
log_ids = map(lambda x: x.id, filter(lambda x: x.history, log_ids))
|
||||
log_ids = map(lambda x: x.id, filter(lambda x: x.email_from, log_ids))
|
||||
msg_val = case_info + '\n\n' + self.get_whole_history(cr, uid, log_ids, context=context)
|
||||
|
||||
elif history_type == 'latest':
|
||||
log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
|
||||
log_ids = filter(lambda x: x.history and x.id, log_ids)
|
||||
log_ids = filter(lambda x: x.email_from and x.id, log_ids)
|
||||
if not log_ids:
|
||||
msg_val = case_info
|
||||
else:
|
||||
|
@ -170,6 +170,13 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
email = self.pool.get('res.partner.address').browse(cr, uid, address_id).email
|
||||
return {'value': {'email_to' : email}}
|
||||
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
super(crm_lead_forward_to_partner, self).send_mail(cr, uid, ids, context=context)
|
||||
self.action_forward(cr, uid, ids, context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def action_forward(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Forward the lead to a partner
|
||||
|
@ -180,15 +187,13 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
case_pool = self.pool.get(context.get('active_model'))
|
||||
res_id = context and context.get('active_id', False) or False
|
||||
case = case_pool.browse(cr, uid, res_id, context=context)
|
||||
|
||||
context.update({'mail': 'forward'})
|
||||
super(crm_lead_forward_to_partner, self).action_send(cr, uid, ids, context=context)
|
||||
|
||||
to_write = {'date_assign': time.strftime('%Y-%m-%d')}
|
||||
if (this.name == 'partner' and this.partner_id):
|
||||
if (this.send_to == 'partner' and this.partner_id):
|
||||
to_write['partner_assigned_id'] = this.partner_id.id
|
||||
|
||||
if this.name == 'user':
|
||||
if this.send_to == 'user':
|
||||
to_write.update({'user_id' : this.user_id.id})
|
||||
email_re = r'([^ ,<@]+@[^> ,]+)'
|
||||
email_cc = re.findall(email_re, case.email_cc or '')
|
||||
|
@ -202,7 +207,6 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
new_cc.append(to)
|
||||
to_write.update({'email_cc' : ', '.join(new_cc) })
|
||||
case_pool.write(cr, uid, case.id, to_write, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def get_lead_details(self, cr, uid, lead_id, context=None):
|
||||
|
@ -285,14 +289,12 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
body = self._get_case_history(cr, uid, defaults.get('history', 'latest'), lead.id, context=context)
|
||||
defaults.update({
|
||||
'subject' : '%s: %s - %s' % (_('Fwd'), 'Openerp lead forward', lead.name),
|
||||
'body' : body,
|
||||
'body_text' : body,
|
||||
'email_cc' : email_cc,
|
||||
'email_to' : email or 'dummy@dummy.ly'
|
||||
})
|
||||
return defaults
|
||||
|
||||
crm_lead_forward_to_partner()
|
||||
|
||||
class crm_lead_mass_forward_to_partner(osv.osv_memory):
|
||||
_name = 'crm.lead.mass.forward.to.partner'
|
||||
_inherit = 'crm.lead.forward.to.partner'
|
||||
|
@ -312,13 +314,11 @@ class crm_lead_mass_forward_to_partner(osv.osv_memory):
|
|||
continue
|
||||
|
||||
context.update({'active_id' : case.id})
|
||||
value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history'], context=context)
|
||||
value = self.default_get(cr, uid, ['body_text', 'email_to', 'email_cc', 'subject', 'history'], context=context)
|
||||
self.write(cr, uid, ids, value, context=context)
|
||||
self.action_forward(cr,uid, ids, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
crm_lead_mass_forward_to_partner()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,41 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="crm_lead_forward_to_partner_form">
|
||||
<field name="name">crm_lead_forward_to_partner</field>
|
||||
<field name="model">crm.lead.forward.to.partner</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="crm.crm_send_new_mail_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="email_from" position="before">
|
||||
<form string="Send Mail">
|
||||
<separator string="Forward to Partner" colspan="4" />
|
||||
<group col="4" colspan="6">
|
||||
<field name="history" colspan="2" on_change="on_change_history(history, context)"/>
|
||||
<field name="name" colspan="2" />
|
||||
<group col="2" colspan="2" attrs="{ 'invisible' : [('name','!=','user')]}">
|
||||
<field name="send_to" colspan="2" />
|
||||
<group col="2" colspan="2" attrs="{ 'invisible' : [('send_to','!=','user')]}">
|
||||
<field name="user_id"
|
||||
attrs="{ 'required' : [('name','=','user')]}"
|
||||
attrs="{ 'required' : [('send_to','=','user')]}"
|
||||
on_change="on_change_email(user_id)" />
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible' : [('name','!=','partner')]}">
|
||||
<field name="partner_id" attrs="{'required' : [('name','=','partner')]}" on_change="on_change_partner(partner_id)" colspan="2" />
|
||||
<group col="4" colspan="4" attrs="{'invisible' : [('send_to','!=','partner')]}">
|
||||
<field name="partner_id" attrs="{'required' : [('send_to','=','partner')]}" on_change="on_change_partner(partner_id)" colspan="2" />
|
||||
<field name="address_id" string="Contact" on_change="on_change_address(address_id)" colspan="2" />
|
||||
</group>
|
||||
</group>
|
||||
<separator string="" colspan="4" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crm_lead_forward_to_partner_form1">
|
||||
<field name="name">crm_lead_forward_to_partner1</field>
|
||||
<field name="model">crm.lead.forward.to.partner</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="crm.crm_send_new_mail_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_send" position="replace">
|
||||
<button name="action_forward" string="Forward" icon="gtk-go-forward" type="object" />
|
||||
</button>
|
||||
<group col="6" colspan="4">
|
||||
<field name="smtp_server_id" widget="selection" colspan="4"/>
|
||||
<field name="email_from" colspan="4" required="1"/>
|
||||
<field name="email_to" colspan="4" required="1"/>
|
||||
<field name="email_cc" colspan="4"/>
|
||||
<field name="email_bcc" colspan="4"/>
|
||||
<field name="reply_to" colspan="4"/>
|
||||
<field name="subject" colspan="4" widget="char" size="512"/>
|
||||
</group>
|
||||
<separator string="" colspan="4"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Body">
|
||||
<field name="body" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<label string="Add here all attachments of the current document you want to include in the Email." colspan="4"/>
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4" colspan="4">
|
||||
<label string="" colspan="1"/>
|
||||
<button icon="gtk-close" special="cancel" string="Close"/>
|
||||
<button icon="gtk-ok" name="send_mail" string="Send" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:15+0000\n"
|
||||
"PO-Revision-Date: 2011-08-25 17:35+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2011-09-13 09:03+0000\n"
|
||||
"Last-Translator: John Bradshaw <Unknown>\n"
|
||||
"Language-Team: English (United Kingdom) <en_GB@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: 2011-09-05 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13830)\n"
|
||||
"X-Launchpad-Export-Date: 2011-09-14 04:40+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: field:decimal.precision,digits:0
|
||||
|
@ -31,7 +31,7 @@ msgstr "Decimal Precision"
|
|||
#: model:ir.actions.act_window,name:decimal_precision.action_decimal_precision_form
|
||||
#: model:ir.ui.menu,name:decimal_precision.menu_decimal_precision_form
|
||||
msgid "Decimal Accuracy Definitions"
|
||||
msgstr ""
|
||||
msgstr "Decimal Accuracy Definitions"
|
||||
|
||||
#. module: decimal_precision
|
||||
#: model:ir.module.module,description:decimal_precision.module_meta_information
|
||||
|
|
|
@ -71,7 +71,7 @@ class delivery_carrier(osv.osv):
|
|||
'free_if_more_than': fields.boolean('Free If More Than'),
|
||||
'amount': fields.float('Amount'),
|
||||
'use_detailed_pricelist': fields.boolean('Use Detailed Pricelist'),
|
||||
'pricelist_ids': fields.one2many('delivery.grid', 'carrier_id', 'Price List'),
|
||||
'pricelist_ids': fields.one2many('delivery.grid', 'carrier_id', 'Advanced Pricing'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
<record id="delivery_product" model="product.product">
|
||||
<field name="name">Delivery by Poste</field>
|
||||
<field name="default_code">Delivery</field>
|
||||
<field name="type">service</field>
|
||||
<field model="product.category" name="categ_id" search="[]"/>
|
||||
</record>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Carrier">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="price" invisible="'order_id' not in context"/>
|
||||
</tree>
|
||||
|
@ -22,10 +21,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Carrier">
|
||||
<group colspan="4" col="4" name="general">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
<field name="product_id" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<separator string="Pricing Information" colspan="6"/>
|
||||
<group colspan="2" col="4">
|
||||
<field name="normal_price" select="1" colspan="4"/>
|
||||
|
@ -82,7 +80,7 @@
|
|||
<field name="help">Define the delivery methods you are using and their pricing in order to reinvoice the delivery costs when you are doing invoicing based on delivery orders</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_delivery_carrier_form" id="menu_action_delivery_carrier_form" parent="menu_delivery" groups="base.group_extended"/>
|
||||
<menuitem action="action_delivery_carrier_form" id="menu_action_delivery_carrier_form" parent="menu_delivery"/>
|
||||
|
||||
<!-- Delivery Grids -->
|
||||
<record id="view_delivery_grid_tree" model="ir.ui.view">
|
||||
|
@ -132,7 +130,7 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="help">The delivery price list allows you to compute the cost and sales price of the delivery according to the weight of the products and other criteria. You can define several price lists for one delivery method, per country or a zone in a specific country defined by a postal code range.</field>
|
||||
</record>
|
||||
<menuitem action="action_delivery_grid_form" id="menu_action_delivery_grid_form" parent="menu_delivery"/>
|
||||
<menuitem action="action_delivery_grid_form" id="menu_action_delivery_grid_form" parent="menu_delivery" groups="base.group_extended"/>
|
||||
|
||||
<record id="view_delivery_grid_line_form" model="ir.ui.view">
|
||||
<field name="name">delivery.grid.line.form</field>
|
||||
|
|
|
@ -252,7 +252,7 @@ class document_file(osv.osv):
|
|||
ids = ids2
|
||||
if 'file_size' in vals: # only write that field using direct SQL calls
|
||||
del vals['file_size']
|
||||
if len(ids) and len(vals):
|
||||
if ids and vals:
|
||||
result = super(document_file,self).write(cr, uid, ids, vals, context=context)
|
||||
cr.commit() # ?
|
||||
return result
|
||||
|
|
|
@ -11,6 +11,7 @@ import fnmatch
|
|||
|
||||
import pooler
|
||||
import netsvc
|
||||
import sql_db
|
||||
|
||||
from service import security
|
||||
from osv import osv
|
||||
|
@ -68,7 +69,7 @@ class abstracted_fs(object):
|
|||
db, cr = None, None
|
||||
try:
|
||||
try:
|
||||
db = pooler.get_db(db_name)
|
||||
db = sql_db.db_connect(db_name)
|
||||
cr = db.cursor()
|
||||
cr.execute("SELECT 1 FROM pg_class WHERE relkind = 'r' AND relname = 'ir_module_module'")
|
||||
if not cr.fetchone():
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
import pooler
|
||||
import sql_db
|
||||
|
||||
import os
|
||||
import time
|
||||
|
@ -361,7 +362,7 @@ class openerp_dav_handler(dav_interface):
|
|||
for db_name in result:
|
||||
cr = None
|
||||
try:
|
||||
db = pooler.get_db(db_name)
|
||||
db = sql_db.db_connect(db_name)
|
||||
cr = db.cursor()
|
||||
cr.execute("SELECT id FROM ir_module_module WHERE name = 'document' AND state='installed' ")
|
||||
res=cr.fetchone()
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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 General Public License as published by
|
||||
|
@ -19,9 +19,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import email_template_account
|
||||
import email_template
|
||||
import email_template_mailbox
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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 General Public License as published by
|
||||
|
@ -21,32 +21,47 @@
|
|||
##############################################################################
|
||||
|
||||
{
|
||||
"name" : "Email Template for OpenERP",
|
||||
"version" : "0.7 RC",
|
||||
"name" : "Email Templates",
|
||||
"version" : "1.1",
|
||||
"author" : "Openlabs",
|
||||
"website" : "http://openerp.com",
|
||||
"category" : "Tools",
|
||||
'complexity': "expert",
|
||||
"depends" : ['marketing', 'base_tools'],
|
||||
"depends" : ['mail'],
|
||||
"description": """
|
||||
Email Template is extraction of Power Email basically just to send emails.
|
||||
==========================================================================
|
||||
Email Templating (simplified version of the original Power Email by Openlabs)
|
||||
=============================================================================
|
||||
|
||||
You can define email accounts(server, port, mail format - HTML/Text/Both)
|
||||
and email templates (resource, recipient, subject, body, attachments).
|
||||
Lets you design complete email templates related to any OpenERP document (Sale
|
||||
Orders, Invoices and so on), including sender, recipient, subject, body (HTML and
|
||||
Text). You may also automatically attach files to your templates, or print and
|
||||
attach a report.
|
||||
|
||||
For advanced use, the templates may include dynamic attributes of the document
|
||||
they are related to. For example, you may use the name of a Partner's country
|
||||
when writing to them, also providing a safe default in case the attribute is
|
||||
not defined. Each template contains a built-in assistant to help with the
|
||||
inclusion of these dynamic values.
|
||||
|
||||
If you enable the option, a composition assistant will also appear in the sidebar
|
||||
of the OpenERP documents to which the template applies (e.g. Invoices).
|
||||
This serves as a quick way to send a new email based on the template, after
|
||||
reviewing and adapting the contents, if needed.
|
||||
This composition assistant will also turn into a mass mailing system when called
|
||||
for multiple documents at once.
|
||||
|
||||
These email templates are also at the heart of the marketing campaign system
|
||||
(see the ``marketing_campaign`` application), if you need to automate larger
|
||||
campaigns on any OpenERP document.
|
||||
|
||||
Technical note: only the templating system of the original Power Email by
|
||||
Openlabs was kept
|
||||
|
||||
For each email template, you can have OpenERP generate a Wizard Action / Button
|
||||
that will be related to the object. So if you choose to do marketing campaigns
|
||||
for leads, the action will be added to the right side panel of the Lead form.
|
||||
""",
|
||||
"init_xml": ['email_template_scheduler_data.xml'],
|
||||
"update_xml": [
|
||||
'security/email_template_security.xml',
|
||||
'email_template_workflow.xml',
|
||||
'email_template_account_view.xml',
|
||||
"data": [
|
||||
'wizard/email_template_preview_view.xml',
|
||||
'email_template_view.xml',
|
||||
'email_template_mailbox_view.xml',
|
||||
'wizard/email_template_send_wizard_view.xml',
|
||||
'wizard/email_compose_message_view.xml',
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
"installable": True,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,470 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import re
|
||||
import smtplib
|
||||
import base64
|
||||
from email import Encoders
|
||||
from email.mime.base import MIMEBase
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.header import decode_header, Header
|
||||
from email.utils import formatdate
|
||||
import netsvc
|
||||
import datetime
|
||||
from tools.translate import _
|
||||
import tools
|
||||
import logging
|
||||
|
||||
EMAIL_PATTERN = re.compile(r'([^()\[\] ,<:\\>@";]+@[^()\[\] ,<:\\>@";]+)') # See RFC822
|
||||
def extract_emails(emails_str):
|
||||
"""
|
||||
Returns a list of email addresses recognized in a string, ignoring the rest of the string.
|
||||
extract_emails('a@b.com,c@bcom, "John Doe" <d@b.com> , e@b.com') -> ['a@b.com','c@bcom', 'd@b.com', 'e@b.com']"
|
||||
"""
|
||||
return EMAIL_PATTERN.findall(emails_str)
|
||||
|
||||
|
||||
def extract_emails_from_dict(addresses={}):
|
||||
"""
|
||||
Extracts email addresses from a dictionary with comma-separated address string values, handling
|
||||
separately the To, CC, BCC and Reply-To addresses.
|
||||
|
||||
:param addresses: a dictionary of addresses in the form {'To': 'a@b.com,c@bcom; d@b.com;e@b.com' , 'CC': 'e@b.com;f@b.com', ... }
|
||||
:return: a dictionary with a list of separate addresses for each header (To, CC, BCC), with an additional key 'all-recipients'
|
||||
containing all addresses for the 'To', 'CC', 'BCC' entries.
|
||||
"""
|
||||
result = {'all-recipients':[]}
|
||||
keys = ['To', 'CC', 'BCC', 'Reply-To']
|
||||
for each in keys:
|
||||
emails = extract_emails(addresses.get(each, u''))
|
||||
while u'' in emails:
|
||||
emails.remove(u'')
|
||||
result[each] = emails
|
||||
if each != 'Reply-To':
|
||||
result['all-recipients'].extend(emails)
|
||||
return result
|
||||
|
||||
class email_template_account(osv.osv):
|
||||
"""
|
||||
Object to store email account settings
|
||||
"""
|
||||
_name = "email_template.account"
|
||||
_known_content_types = ['multipart/mixed',
|
||||
'multipart/alternative',
|
||||
'multipart/related',
|
||||
'text/plain',
|
||||
'text/html'
|
||||
]
|
||||
_columns = {
|
||||
'name': fields.char('Description',
|
||||
size=64, required=True,
|
||||
readonly=True, select=True,
|
||||
help="The description is used as the Sender name along with the provided From Email, \
|
||||
unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'auto_delete': fields.boolean('Auto Delete', size=64, readonly=True,
|
||||
help="Permanently delete emails after sending",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'user':fields.many2one('res.users',
|
||||
'Related User', required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'email_id': fields.char('From Email',
|
||||
size=120, required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]} ,
|
||||
help="eg: 'john@doe.com' or 'John Doe <john@doe.com>'"),
|
||||
'smtpserver': fields.char('Server',
|
||||
size=120, required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]},
|
||||
help="Enter name of outgoing server, eg: smtp.yourdomain.com"),
|
||||
'smtpport': fields.integer('SMTP Port',
|
||||
size=64, required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]},
|
||||
help="Enter port number, eg: 25 or 587"),
|
||||
'smtpuname': fields.char('User Name',
|
||||
size=120, required=False,
|
||||
readonly=True, states={'draft':[('readonly', False)]},
|
||||
help="Specify the username if your SMTP server requires authentication, "
|
||||
"otherwise leave it empty."),
|
||||
'smtppass': fields.char('Password',
|
||||
size=120, invisible=True,
|
||||
required=False, readonly=True,
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'smtptls':fields.boolean('TLS',
|
||||
states={'draft':[('readonly', False)]}, readonly=True),
|
||||
|
||||
'smtpssl':fields.boolean('SSL/TLS (only in python 2.6)',
|
||||
states={'draft':[('readonly', False)]}, readonly=True),
|
||||
'send_pref':fields.selection([
|
||||
('html', 'HTML, otherwise Text'),
|
||||
('text', 'Text, otherwise HTML'),
|
||||
('alternative', 'Both HTML & Text (Alternative)'),
|
||||
('mixed', 'Both HTML & Text (Mixed)')
|
||||
], 'Mail Format', required=True),
|
||||
'company':fields.selection([
|
||||
('yes', 'Yes'),
|
||||
('no', 'No')
|
||||
], 'Corporate',
|
||||
readonly=True,
|
||||
help="Select if this mail account does not belong " \
|
||||
"to specific user but to the organization as a whole. " \
|
||||
"eg: info@companydomain.com",
|
||||
required=True, states={
|
||||
'draft':[('readonly', False)]
|
||||
}),
|
||||
|
||||
'state':fields.selection([
|
||||
('draft', 'Initiated'),
|
||||
('suspended', 'Suspended'),
|
||||
('approved', 'Approved')
|
||||
],
|
||||
'State', required=True, readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'name':lambda self, cursor, user, context:self.pool.get(
|
||||
'res.users'
|
||||
).read(
|
||||
cursor,
|
||||
user,
|
||||
user,
|
||||
['name'],
|
||||
context
|
||||
)['name'],
|
||||
'state':lambda * a:'draft',
|
||||
'smtpport':lambda *a:25,
|
||||
'smtpserver':lambda *a:'localhost',
|
||||
'company':lambda *a:'yes',
|
||||
'user':lambda self, cursor, user, context:user,
|
||||
'send_pref':lambda *a: 'html',
|
||||
'smtptls':lambda *a:True,
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
'email_uniq',
|
||||
'unique (email_id)',
|
||||
'Another setting already exists with this email ID !')
|
||||
]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
return [(a["id"], "%s (%s)" % (a['email_id'], a['name'])) for a in self.read(cr, uid, ids, ['name', 'email_id'], context=context)]
|
||||
|
||||
def _constraint_unique(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
This makes sure that you dont give personal
|
||||
users two accounts with same ID (Validated in sql constaints)
|
||||
However this constraint exempts company accounts.
|
||||
Any no of co accounts for a user is allowed
|
||||
"""
|
||||
if self.read(cursor, user, ids, ['company'])[0]['company'] == 'no':
|
||||
accounts = self.search(cursor, user, [
|
||||
('user', '=', user),
|
||||
('company', '=', 'no')
|
||||
])
|
||||
if len(accounts) > 1 :
|
||||
return False
|
||||
else :
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_constraint_unique,
|
||||
'Error: You are not allowed to have more than 1 account.',
|
||||
[])
|
||||
]
|
||||
|
||||
def get_outgoing_server(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
Returns the Out Going Connection (SMTP) object
|
||||
|
||||
@attention: DO NOT USE except_osv IN THIS METHOD
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param ids: ID/list of ids of current object for
|
||||
which connection is required
|
||||
First ID will be chosen from lists
|
||||
@param context: Context
|
||||
|
||||
@return: SMTP server object or Exception
|
||||
"""
|
||||
#Type cast ids to integer
|
||||
if type(ids) == list:
|
||||
ids = ids[0]
|
||||
this_object = self.browse(cursor, user, ids, context=context)
|
||||
if this_object:
|
||||
if this_object.smtpserver and this_object.smtpport:
|
||||
try:
|
||||
if this_object.smtpssl:
|
||||
serv = smtplib.SMTP_SSL(this_object.smtpserver, this_object.smtpport)
|
||||
else:
|
||||
serv = smtplib.SMTP(this_object.smtpserver, this_object.smtpport)
|
||||
if this_object.smtptls:
|
||||
serv.ehlo()
|
||||
serv.starttls()
|
||||
serv.ehlo()
|
||||
except Exception, error:
|
||||
raise error
|
||||
try:
|
||||
if serv.has_extn('AUTH') or this_object.smtpuname or this_object.smtppass:
|
||||
serv.login(str(this_object.smtpuname), str(this_object.smtppass))
|
||||
except Exception, error:
|
||||
raise error
|
||||
return serv
|
||||
raise Exception(_("SMTP SERVER or PORT not specified"))
|
||||
raise Exception(_("Core connection for the given ID does not exist"))
|
||||
|
||||
def check_outgoing_connection(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
checks SMTP credentials and confirms if outgoing connection works
|
||||
(Attached to button)
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param ids: list of ids of current object for
|
||||
which connection is required
|
||||
@param context: Context
|
||||
"""
|
||||
try:
|
||||
self.get_outgoing_server(cursor, user, ids, context)
|
||||
raise osv.except_osv(_("SMTP Test Connection Was Successful"), '')
|
||||
except osv.except_osv, success_message:
|
||||
raise success_message
|
||||
except Exception, error:
|
||||
raise osv.except_osv(
|
||||
_("Out going connection test failed"),
|
||||
_("Reason: %s") % tools.ustr(error)
|
||||
)
|
||||
|
||||
def do_approval(self, cr, uid, ids, context=None):
|
||||
#TODO: Check if user has rights
|
||||
self.write(cr, uid, ids, {'state':'approved'}, context=context)
|
||||
# wf_service = netsvc.LocalService("workflow")
|
||||
|
||||
def smtp_connection(self, cursor, user, id, context=None):
|
||||
"""
|
||||
This method should now wrap smtp_connection
|
||||
"""
|
||||
#This function returns a SMTP server object
|
||||
logger = netsvc.Logger()
|
||||
core_obj = self.browse(cursor, user, id, context=context)
|
||||
if core_obj.smtpserver and core_obj.smtpport and core_obj.state == 'approved':
|
||||
try:
|
||||
serv = self.get_outgoing_server(cursor, user, id, context)
|
||||
except Exception, error:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed on login. Probable Reason:Could not login to server\nError: %s") % (id, tools.ustr(error)))
|
||||
return False
|
||||
#Everything is complete, now return the connection
|
||||
return serv
|
||||
else:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Account not approved") % id)
|
||||
return False
|
||||
|
||||
#**************************** MAIL SENDING FEATURES ***********************#
|
||||
|
||||
|
||||
|
||||
|
||||
def send_mail(self, cr, uid, ids, addresses, subject='', body=None, payload=None, message_id=None, context=None):
|
||||
#TODO: Replace all this with a single email object
|
||||
if body is None:
|
||||
body = {}
|
||||
if payload is None:
|
||||
payload = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
logger = netsvc.Logger()
|
||||
for id in ids:
|
||||
core_obj = self.browse(cr, uid, id, context)
|
||||
serv = self.smtp_connection(cr, uid, id)
|
||||
if serv:
|
||||
try:
|
||||
# Prepare multipart containers depending on data
|
||||
text_subtype = (core_obj.send_pref == 'alternative') and 'alternative' or 'mixed'
|
||||
# Need a multipart/mixed wrapper for attachments if content is alternative
|
||||
if payload and text_subtype == 'alternative':
|
||||
payload_part = MIMEMultipart(_subtype='mixed')
|
||||
text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
payload_part.attach(text_part)
|
||||
else:
|
||||
# otherwise a single multipart/mixed will do the whole job
|
||||
payload_part = text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
|
||||
if subject:
|
||||
payload_part['Subject'] = subject
|
||||
from_email = core_obj.email_id
|
||||
if '<' in from_email:
|
||||
# We have a structured email address, keep it untouched
|
||||
payload_part['From'] = Header(core_obj.email_id, 'utf-8').encode()
|
||||
else:
|
||||
# Plain email address, construct a structured one based on the name:
|
||||
sender_name = Header(core_obj.name, 'utf-8').encode()
|
||||
payload_part['From'] = sender_name + " <" + core_obj.email_id + ">"
|
||||
payload_part['Organization'] = tools.ustr(core_obj.user.company_id.name)
|
||||
payload_part['Date'] = formatdate()
|
||||
addresses_l = extract_emails_from_dict(addresses)
|
||||
if addresses_l['To']:
|
||||
payload_part['To'] = u','.join(addresses_l['To'])
|
||||
if addresses_l['CC']:
|
||||
payload_part['CC'] = u','.join(addresses_l['CC'])
|
||||
if addresses_l['Reply-To']:
|
||||
payload_part['Reply-To'] = addresses_l['Reply-To'][0]
|
||||
if message_id:
|
||||
payload_part['Message-ID'] = message_id
|
||||
if body.get('text', False):
|
||||
temp_body_text = body.get('text', '')
|
||||
l = len(temp_body_text.replace(' ', '').replace('\r', '').replace('\n', ''))
|
||||
if l == 0:
|
||||
body['text'] = u'No Mail Message'
|
||||
# Attach parts into message container.
|
||||
# According to RFC 2046, the last part of a multipart message, in this case
|
||||
# the HTML message, is best and preferred.
|
||||
if core_obj.send_pref in ('text', 'mixed', 'alternative'):
|
||||
body_text = body.get('text', u'<Empty Message>')
|
||||
body_text = tools.ustr(body_text)
|
||||
text_part.attach(MIMEText(body_text.encode("utf-8"), _charset='UTF-8'))
|
||||
if core_obj.send_pref in ('html', 'mixed', 'alternative'):
|
||||
html_body = body.get('html', u'')
|
||||
if len(html_body) == 0 or html_body == u'':
|
||||
html_body = body.get('text', u'<p><Empty Message></p>').replace('\n', '<br/>').replace('\r', '<br/>')
|
||||
html_body = tools.ustr(html_body)
|
||||
text_part.attach(MIMEText(html_body.encode("utf-8"), _subtype='html', _charset='UTF-8'))
|
||||
|
||||
#Now add attachments if any, wrapping into a container multipart/mixed if needed
|
||||
if payload:
|
||||
for file in payload:
|
||||
part = MIMEBase('application', "octet-stream")
|
||||
part.set_payload(base64.decodestring(payload[file]))
|
||||
part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
|
||||
Encoders.encode_base64(part)
|
||||
payload_part.attach(part)
|
||||
except Exception, error:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:MIME Error\nDescription: %s") % (id, tools.ustr(error)))
|
||||
return {'error_msg': _("Server Send Error\nDescription: %s")%error}
|
||||
try:
|
||||
serv.sendmail(payload_part['From'], addresses_l['all-recipients'], payload_part.as_string())
|
||||
except Exception, error:
|
||||
logging.getLogger('email_template').error(_("Mail from Account %s failed. Probable Reason: Server Send Error\n Description: %s"), id, tools.ustr(error), exc_info=True)
|
||||
return {'error_msg': _("Server Send Error\nDescription: %s") % tools.ustr(error)}
|
||||
#The mail sending is complete
|
||||
serv.close()
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_INFO, _("Mail from Account %s successfully Sent.") % (id))
|
||||
return True
|
||||
else:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Account not approved") % id)
|
||||
return {'nodestroy':True,'error_msg': _("Mail from Account %s failed. Probable Reason:Account not approved")% id}
|
||||
|
||||
def extracttime(self, time_as_string):
|
||||
"""
|
||||
TODO: DOC THis
|
||||
"""
|
||||
logger = netsvc.Logger()
|
||||
#The standard email dates are of format similar to:
|
||||
#Thu, 8 Oct 2009 09:35:42 +0200
|
||||
date_as_date = False
|
||||
convertor = {'+':1, '-':-1}
|
||||
try:
|
||||
time_as_string = time_as_string.replace(',', '')
|
||||
date_list = time_as_string.split(' ')
|
||||
date_temp_str = ' '.join(date_list[1:5])
|
||||
if len(date_list) >= 6:
|
||||
sign = convertor.get(date_list[5][0], False)
|
||||
else:
|
||||
sign = False
|
||||
try:
|
||||
dt = datetime.datetime.strptime(
|
||||
date_temp_str,
|
||||
"%d %b %Y %H:%M:%S")
|
||||
except:
|
||||
try:
|
||||
dt = datetime.datetime.strptime(
|
||||
date_temp_str,
|
||||
"%d %b %Y %H:%M")
|
||||
except:
|
||||
return False
|
||||
if sign:
|
||||
try:
|
||||
offset = datetime.timedelta(
|
||||
hours=sign * int(
|
||||
date_list[5][1:3]
|
||||
),
|
||||
minutes=sign * int(
|
||||
date_list[5][3:5]
|
||||
)
|
||||
)
|
||||
except Exception, e2:
|
||||
"""Looks like UT or GMT, just forget decoding"""
|
||||
return False
|
||||
else:
|
||||
offset = datetime.timedelta(hours=0)
|
||||
dt = dt + offset
|
||||
date_as_date = dt.strftime('%Y-%m-%d %H:%M:%S')
|
||||
except Exception, e:
|
||||
logger.notifyChannel(
|
||||
_("Email Template"),
|
||||
netsvc.LOG_WARNING,
|
||||
_(
|
||||
"Datetime Extraction failed.Date:%s \
|
||||
\tError:%s") % (
|
||||
time_as_string,
|
||||
tools.ustr(e))
|
||||
)
|
||||
return date_as_date
|
||||
|
||||
def send_receive(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
ctx = context.copy()
|
||||
ctx['filters'] = [('account_id', '=', id)]
|
||||
self.pool.get('email_template.mailbox').send_all_mail(cr, uid, [], context=ctx)
|
||||
return True
|
||||
|
||||
def decode_header_text(self, text):
|
||||
""" Decode internationalized headers RFC2822.
|
||||
To, CC, BCC, Subject fields can contain
|
||||
text slices with different encodes, like:
|
||||
=?iso-8859-1?Q?Enric_Mart=ED?= <enricmarti@company.com>,
|
||||
=?Windows-1252?Q?David_G=F3mez?= <david@company.com>
|
||||
Sometimes they include extra " character at the beginning/
|
||||
end of the contact name, like:
|
||||
"=?iso-8859-1?Q?Enric_Mart=ED?=" <enricmarti@company.com>
|
||||
and decode_header() does not work well, so we use regular
|
||||
expressions (?= ? ? ?=) to split the text slices
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
p = re.compile("(=\?.*?\?.\?.*?\?=)")
|
||||
text2 = ''
|
||||
try:
|
||||
for t2 in p.split(text):
|
||||
text2 += ''.join(
|
||||
[s.decode(
|
||||
t or 'ascii'
|
||||
) for (s, t) in decode_header(t2)]
|
||||
).encode('utf-8')
|
||||
except:
|
||||
return text
|
||||
return text2
|
||||
|
||||
email_template_account()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,124 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<menuitem name="Marketing" icon="terp-crm" id="base.marketing_menu" sequence="17"
|
||||
groups="marketing.group_marketing_user,marketing.group_marketing_manager"/>
|
||||
<menuitem name="Emails" id="base.menu_emails" parent="base.marketing_menu" sequence="5"/>
|
||||
<menuitem name="Email Template" id="menu_email_template" parent="base.menu_emails"/>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_account_form">
|
||||
<field name="name">email_template.account.form</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Account Configuration">
|
||||
<group colspan="2">
|
||||
<field name="name" select="1" />
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Outgoing">
|
||||
<separator string="Server Information" colspan="4" />
|
||||
<group colspan="4" col="4">
|
||||
<field name="smtpserver" select="1"/>
|
||||
<button name="check_outgoing_connection" type="object" string="Test Outgoing Connection" icon="gtk-network" colspan="2"/>
|
||||
<field name="smtpport" select="2" />
|
||||
<field name="smtpssl" select="2" />
|
||||
<field name="smtptls" select="2" />
|
||||
<field name="auto_delete" />
|
||||
</group>
|
||||
<separator string="User Information" colspan="4" />
|
||||
<group col="2" colspan="2">
|
||||
<field name="email_id" select="1" colspan="2" />
|
||||
<field name="smtppass" password="True" colspan="2" />
|
||||
<field name="company" select="2" colspan="2" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<field name="smtpuname" select="1" colspan="2" />
|
||||
<field name="user" select="2" colspan="2" />
|
||||
<field name="send_pref" colspan="2" />
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<group colspan="4" col="10">
|
||||
<field name="state" select="1"/>
|
||||
<button string="Approve Account" name="button_approval" states="draft" type="workflow" icon="terp-camera_test"/>
|
||||
<button string="Suspend Account" name="button_suspended" states="approved" type="workflow" icon="gtk-cancel"/>
|
||||
<button string="Request Re-activation" name="get_reapprove" states="suspended" type="workflow" icon="gtk-convert"/>
|
||||
<button string="Send/Receive" name="send_receive" states="approved" type="object" icon="terp-check"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_account_tree">
|
||||
<field name="name">email_template.account.tree</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('suspended','approved')" string="Email Accounts">
|
||||
<field name="name" />
|
||||
<field name="email_id" />
|
||||
<field name="smtpuname" />
|
||||
<field name="user" />
|
||||
<field name="smtpserver" />
|
||||
<field name="smtpport" />
|
||||
<field name="auto_delete" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_email_template_account_search" model="ir.ui.view">
|
||||
<field name="name">email_template.account.search</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Email Accounts">
|
||||
<filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-camera_test" string="Approved" domain="[('state','=','approved')]"/>
|
||||
<filter icon="terp-emblem-important" string="Suspended" domain="[('state','=','suspended')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-home" string="Company Accounts" domain="[('company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="user" select="1">
|
||||
<filter icon="terp-personal" help="My Accounts" name="my" domain="[('user','=',uid)]"/>
|
||||
</field>
|
||||
<field name="name" select="1"/>
|
||||
<field name="email_id" select="1"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_account_tree_all">
|
||||
<field name="name">Accounts</field>
|
||||
<field name="res_model">email_template.account</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
<field name="view_id" ref="email_template_account_tree" />
|
||||
<field name="context">{'search_default_draft': 1, 'search_default_my': 1}</field>
|
||||
<field name="search_view_id" ref="view_email_template_account_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Configuration" parent="base.marketing_menu"
|
||||
id="base.menu_marketing_config_root" sequence="20" groups="base.group_system"/>
|
||||
|
||||
<menuitem name="Email Template" id="menu_email_template_configuration" parent="base.menu_marketing_config_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_template_account_all" parent="menu_email_template_configuration" action="action_email_template_account_tree_all"/>
|
||||
|
||||
<menuitem name="Configuration" parent="base.menu_tools"
|
||||
id="base.menu_lunch_survey_root" sequence="20" />
|
||||
|
||||
<menuitem name="Email Template" id="menu_email_template_config_tools"
|
||||
parent="base.menu_lunch_survey_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_account_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_account_tree_all" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import time
|
||||
import netsvc
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
||||
LOGGER = netsvc.Logger()
|
||||
|
||||
class email_template_mailbox(osv.osv):
|
||||
_name = "email_template.mailbox"
|
||||
_description = 'Email Mailbox'
|
||||
_rec_name = "subject"
|
||||
_order = "date_mail desc"
|
||||
|
||||
def run_mail_scheduler(self, cursor, user, context=None):
|
||||
"""
|
||||
This method is called by OpenERP Scheduler
|
||||
to periodically send emails
|
||||
"""
|
||||
try:
|
||||
self.send_all_mail(cursor, user, context=context)
|
||||
except Exception, e:
|
||||
LOGGER.notifyChannel(
|
||||
"Email Template",
|
||||
netsvc.LOG_ERROR,
|
||||
_("Error sending mail: %s") % e)
|
||||
|
||||
def send_all_mail(self, cr, uid, ids=None, context=None):
|
||||
if ids is None:
|
||||
ids = []
|
||||
if context is None:
|
||||
context = {}
|
||||
filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
|
||||
if 'filters' in context.keys():
|
||||
for each_filter in context['filters']:
|
||||
filters.append(each_filter)
|
||||
ids = self.search(cr, uid, filters, context=context)
|
||||
self.write(cr, uid, ids, {'state':'sending'}, context)
|
||||
self.send_this_mail(cr, uid, ids, context)
|
||||
return True
|
||||
|
||||
def send_this_mail(self, cr, uid, ids=None, context=None):
|
||||
#previous method to send email (link with email account can be found at the revision 4172 and below
|
||||
result = True
|
||||
attachment_pool = self.pool.get('ir.attachment')
|
||||
for id in (ids or []):
|
||||
try:
|
||||
account_obj = self.pool.get('email_template.account')
|
||||
values = self.read(cr, uid, id, [], context)
|
||||
payload = {}
|
||||
if values['attachments_ids']:
|
||||
for attid in values['attachments_ids']:
|
||||
attachment = attachment_pool.browse(cr, uid, attid, context)#,['datas_fname','datas'])
|
||||
payload[attachment.datas_fname] = attachment.datas
|
||||
result = account_obj.send_mail(cr, uid,
|
||||
[values['account_id'][0]],
|
||||
{'To':values.get('email_to') or u'',
|
||||
'CC':values.get('email_cc') or u'',
|
||||
'BCC':values.get('email_bcc') or u'',
|
||||
'Reply-To':values.get('reply_to') or u''},
|
||||
values['subject'] or u'',
|
||||
{'text':values.get('body_text') or u'', 'html':values.get('body_html') or u''},
|
||||
payload=payload,
|
||||
message_id=values['message_id'],
|
||||
context=context)
|
||||
if result == True:
|
||||
account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
|
||||
if account.auto_delete:
|
||||
self.write(cr, uid, id, {'folder': 'trash'}, context=context)
|
||||
self.unlink(cr, uid, [id], context=context)
|
||||
# Remove attachments for this mail
|
||||
attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
|
||||
return result
|
||||
else:
|
||||
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
self.historise(cr, uid, [id], "Email sent successfully", context)
|
||||
else:
|
||||
error = result['error_msg']
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
|
||||
except Exception, error:
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
self.write(cr, uid, id, {'state':'na'}, context)
|
||||
return result
|
||||
|
||||
def historise(self, cr, uid, ids, message='', context=None):
|
||||
for id in ids:
|
||||
history = self.read(cr, uid, id, ['history'], context).get('history', '')
|
||||
self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
|
||||
|
||||
_columns = {
|
||||
'email_from':fields.char(
|
||||
'From',
|
||||
size=64),
|
||||
'email_to':fields.char(
|
||||
'Recipient (To)',
|
||||
size=250,),
|
||||
'email_cc':fields.char(
|
||||
'CC',
|
||||
size=250),
|
||||
'email_bcc':fields.char(
|
||||
'BCC',
|
||||
size=250),
|
||||
'reply_to':fields.char(
|
||||
'Reply-To',
|
||||
size=250),
|
||||
'message_id':fields.char(
|
||||
'Message-ID',
|
||||
size=250),
|
||||
'subject':fields.char(
|
||||
'Subject',
|
||||
size=200,),
|
||||
'body_text':fields.text(
|
||||
'Standard Body (Text)'),
|
||||
'body_html':fields.text(
|
||||
'Body (Rich Text Clients Only)'),
|
||||
'attachments_ids':fields.many2many(
|
||||
'ir.attachment',
|
||||
'mail_attachments_rel',
|
||||
'mail_id',
|
||||
'att_id',
|
||||
'Attachments'),
|
||||
'account_id' :fields.many2one(
|
||||
'email_template.account',
|
||||
'User account',
|
||||
required=True),
|
||||
'user':fields.related(
|
||||
'account_id',
|
||||
'user',
|
||||
type="many2one",
|
||||
relation="res.users",
|
||||
string="User"),
|
||||
'server_ref':fields.integer(
|
||||
'Server Reference of mail',
|
||||
help="Applicable for inward items only"),
|
||||
'mail_type':fields.selection([
|
||||
('multipart/mixed',
|
||||
'Has Attachments'),
|
||||
('multipart/alternative',
|
||||
'Plain Text & HTML with no attachments'),
|
||||
('multipart/related',
|
||||
'Intermixed content'),
|
||||
('text/plain',
|
||||
'Plain Text'),
|
||||
('text/html',
|
||||
'HTML Body'),
|
||||
], 'Mail Contents'),
|
||||
#I like GMAIL which allows putting same mail in many folders
|
||||
#Lets plan it for 0.9
|
||||
'folder':fields.selection([
|
||||
('drafts', 'Drafts'),
|
||||
('outbox', 'Outbox'),
|
||||
('trash', 'Trash'),
|
||||
('sent', 'Sent Items'),
|
||||
], 'Folder', required=True),
|
||||
'state':fields.selection([
|
||||
('na', 'Not Applicable'),
|
||||
('sending', 'Sending'),
|
||||
], 'Status', required=True),
|
||||
'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
|
||||
'history':fields.text(
|
||||
'History',
|
||||
readonly=True,
|
||||
store=True)
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda * a: 'na',
|
||||
'folder': lambda * a: 'outbox',
|
||||
}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
It just changes the folder of the item to "Trash", if it is no in Trash folder yet,
|
||||
or completely deletes it if it is already in Trash.
|
||||
"""
|
||||
to_update = []
|
||||
to_remove = []
|
||||
for mail in self.browse(cr, uid, ids, context=context):
|
||||
if mail.folder == 'trash':
|
||||
to_remove.append(mail.id)
|
||||
else:
|
||||
to_update.append(mail.id)
|
||||
# Changes the folder to trash
|
||||
self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
|
||||
return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
|
||||
|
||||
email_template_mailbox()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,134 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Email Template-->
|
||||
<record model="ir.ui.view" id="email_template_mailbox_form">
|
||||
<field name="name">email_template.mailbox.form</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Emails">
|
||||
<group col="4" colspan="4" name="headers">
|
||||
<field name="email_from" select="1"/>
|
||||
<field name="email_to" required="1" select="1" />
|
||||
<field name="reply_to" select="2"/>
|
||||
<field name="email_cc" select="1"/>
|
||||
<field name="email_bcc" select="2"/>
|
||||
<field name="date_mail" select="2"/>
|
||||
<field name="subject" colspan="4" select="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Standard Body">
|
||||
<separator colspan="4" string="Standard Body" />
|
||||
<notebook colspan="4">
|
||||
<page string="Standard Body (Text)">
|
||||
<field name="body_text" nolabel="1" colspan="4" select="1"/>
|
||||
</page>
|
||||
<page string="Body (HTML-Web Client Only)">
|
||||
<field name="body_html" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
<separator colspan="4" string="" />
|
||||
<group col="4" colspan="4">
|
||||
<field name="state" readonly="1" string="State"/>
|
||||
<button name="send_this_mail" type="object" string="Send Mail" icon="terp-mail-message-new"/>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="Attachments">
|
||||
<separator colspan="4" string="Attachments" />
|
||||
<field name="attachments_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
<field name="account_id" colspan="2" />
|
||||
<field name="server_ref" colspan="2" />
|
||||
<field name="mail_type" colspan="2" />
|
||||
<field name="folder" colspan="2" select="2"/>
|
||||
<field name="message_id" select="2"/>
|
||||
<separator string="History" colspan="4" />
|
||||
<field name="history" nolabel="1" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--============================================= TREE VIEWS =============================================-->
|
||||
<record id="view_email_template_mailbox_tree" model="ir.ui.view">
|
||||
<field name="name">email_template.mailbox.tree</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Emails" colors="blue:folder=='drafts';grey:folder=='trash'">
|
||||
<field name="subject" select="1" />
|
||||
<field name="user" />
|
||||
<field name="email_from" select="1" />
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail" select="2" />
|
||||
<field name="attachments_ids" select="2" />
|
||||
<field name="folder" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_email_template_mailbox_search" model="ir.ui.view">
|
||||
<field name="name">email_template.mailbox.search</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Emails">
|
||||
<filter icon="terp-document-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
|
||||
<filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
|
||||
<filter icon="terp-camera_test" string="Sent" domain="[('folder','=','sent')]"/>
|
||||
<filter icon="terp-mail_delete" string="Trash" domain="[('folder','=','trash')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-personal+" string="Personal Emails" name="personal" domain="[('account_id.company','=','no')]"/>
|
||||
<filter icon="terp-go-home" string="Company Emails" name="company" domain="[('account_id.company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="subject"/>
|
||||
<field name="email_from"/>
|
||||
<field name="user">
|
||||
<filter icon="terp-personal"
|
||||
string="My Emails" help="My Emails" name="myemails"
|
||||
domain="[('account_id.user','=', uid)]" />
|
||||
</field>
|
||||
<newline/>
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_mailbox">
|
||||
<field name="name">Emails</field>
|
||||
<field name="res_model">email_template.mailbox</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_email_template_mailbox_tree" />
|
||||
<field name="context">{'search_default_outbox': 1}</field>
|
||||
<field name="help">An email template is an email document that will be sent as part of a marketing campaign. You can personalize it according to specific customer profile fields, so that a partner name or other partner related information may be inserted automatically.</field>
|
||||
<field name="search_view_id" ref="view_email_template_mailbox_search"/>
|
||||
</record>
|
||||
|
||||
<!--======================================== MENUS ========================================-->
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_personal_mails"
|
||||
parent="menu_email_template"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
<!-- Mailbox menu in Tools -->
|
||||
<menuitem name="Email Template" id="menu_email_template_tools"
|
||||
parent="base.menu_tools" />
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_mails_tools"
|
||||
parent="menu_email_template_tools"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,141 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Email Template Preview -->
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="name">email_template.preview.form</field>
|
||||
<field name="model">email_template.preview</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Preview">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model" />
|
||||
<field name="rel_model_ref" on_change="on_change_ref(rel_model_ref, context)"/>
|
||||
</group>
|
||||
<group col="8" colspan="4">
|
||||
<field name="to" />
|
||||
<field name="cc" />
|
||||
<field name="bcc" />
|
||||
<field name="reply_to" />
|
||||
<field name="message_id" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string= "Body(Text)" colspan="2"/>
|
||||
<separator string= "Body(Html)" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="body_text" nolabel="1" colspan="2"/>
|
||||
<field name="body_html" nolabel="1" colspan="2"/>
|
||||
</group>
|
||||
<field name="report" colspan="2"/>
|
||||
<button icon="gtk-ok" special="cancel" string="OK" colspan="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="wizard_email_template_preview" model="ir.actions.act_window">
|
||||
<field name="name">Template Preview</field>
|
||||
<field name="res_model">email_template.preview</field>
|
||||
<field name="src_model">email_template.preview</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="auto_refresh" eval="1" />
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'template_id':active_id}</field>
|
||||
</record>
|
||||
<!--EMail client Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="email_template_form">
|
||||
<field name="name">email.template.form</field>
|
||||
<field name="model">email.template</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Templates">
|
||||
<field name="name" />
|
||||
<field name="object_name" required="1"
|
||||
on_change="change_model(object_name)" />
|
||||
<field name="model_int_name" invisible="1" />
|
||||
<form string="Templates">
|
||||
<field name="name" required="1"/>
|
||||
<field name="model_id" required="1" on_change="onchange_model_id(model_id)"/>
|
||||
<field name="model" invisible="1"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Mail Details">
|
||||
<page string="Email Details">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Addresses" colspan="2"/>
|
||||
<field name="from_account" required="1"/>
|
||||
<field name="def_to" required="1"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
<field name="email_from" required="1"/>
|
||||
<field name="email_to" required="1"/>
|
||||
<field name="email_cc"/>
|
||||
<field name="email_bcc"/>
|
||||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Options" colspan="2"/>
|
||||
<field name="lang" colspan="4" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<field name="track_campaign_item" colspan="4"/>
|
||||
<field name="user_signature" colspan="4" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Email Content " />
|
||||
<field name="def_subject" colspan="4" required="1" />
|
||||
<separator colspan="2" string="Email Content"/>
|
||||
<field name="subject" colspan="4" required="1"/>
|
||||
<notebook>
|
||||
<page string="Body (Text)">
|
||||
<field name="def_body_text" colspan="4" nolabel="1" />
|
||||
<field name="body_text" colspan="4" width="250" height="250" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Body (Raw HTML)">
|
||||
<field name="def_body_html" colspan="4" nolabel="1" />
|
||||
<label string="Note: This is Raw HTML." colspan="4" />
|
||||
<page string="Body (Rich/HTML)">
|
||||
<field name="body_html" colspan="4" width="250" height="250" nolabel="1"/>
|
||||
<label string="Note: This is Raw HTML." colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<separator colspan="4" string="Expression Builder" />
|
||||
<field name="template_language"
|
||||
on_change="onchange_null_value(model_object_field,sub_model_object_field,null_value,template_language,context)" />
|
||||
<notebook>
|
||||
<page string="Insert Simple Field">
|
||||
|
||||
<page string="Dynamic Values Builder">
|
||||
<field name="model_object_field"
|
||||
domain="[('model_id','=',object_name),('ttype','!=','one2many'),('ttype','!=','many2many')]"
|
||||
on_change="onchange_model_object_field(model_object_field, template_language,context)"
|
||||
colspan="4" />
|
||||
<field name="sub_object" readonly="1" colspan="4" />
|
||||
domain="[('model_id','=',model_id),('ttype','!=','one2many'),('ttype','!=','many2many')]"
|
||||
on_change="onchange_sub_model_object_value_field(model_object_field)"
|
||||
colspan="4"/>
|
||||
<field name="sub_object" readonly="1" colspan="4"/>
|
||||
<field name="sub_model_object_field"
|
||||
domain="[('model_id','=',sub_object),('ttype','!=','one2many'),('ttype','!=','many2many')]"
|
||||
colspan="4"
|
||||
attrs="{'readonly':[('sub_object','=',False)],'required':[('sub_object','!=',False)]}"
|
||||
on_change="onchange_sub_model_object_field(model_object_field,sub_model_object_field,template_language,context)" />
|
||||
on_change="onchange_sub_model_object_value_field(model_object_field,sub_model_object_field)"/>
|
||||
<field name="null_value" colspan="4"
|
||||
on_change="onchange_null_value(model_object_field,sub_model_object_field,null_value,template_language,context)" />
|
||||
<field name="copyvalue" colspan="4" />
|
||||
on_change="onchange_sub_model_object_value_field(model_object_field,sub_model_object_field,null_value)" />
|
||||
<field name="copyvalue" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<button name="%(wizard_email_template_preview)d" string="Preview Template"
|
||||
type="action" colspan="4" target="new" icon="gtk-zoom-fit"/>
|
||||
type="action" colspan="4" target="new" icon="gtk-zoom-fit" context="{'template_id':active_id}"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
<group colspan="2" col="2">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Actions" colspan="2"/>
|
||||
<button name="create_action" string="Create Action" type="object" icon="gtk-execute" colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False), ('ref_ir_value','!=',False)]}"/>
|
||||
<field name="ref_ir_act_window"/>
|
||||
<field name="ref_ir_value"/>
|
||||
<button name="delete_action" string="Delete Action" type="object" icon="gtk-delete" colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False), ('ref_ir_value','=',False)]}"/>
|
||||
<separator string="Sidebar button" colspan="2"/>
|
||||
<button name="create_action" string="Add sidebar button" type="object" icon="gtk-execute"
|
||||
colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False)]}"
|
||||
help="Display a button in the sidebar of related documents to open a composition wizard with this template"
|
||||
/>
|
||||
<field name="ref_ir_act_window" attrs="{'invisible':[('ref_ir_act_window','=',False)]}"/>
|
||||
<field name="ref_ir_value" attrs="{'invisible':[('ref_ir_act_window','=',False)]}"/>
|
||||
<button name="unlink_action" string="Remove sidebar button" type="object" icon="gtk-delete"
|
||||
colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False)]}"
|
||||
help="Remove the sidebar button currently displayed on related documents"
|
||||
/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<group colspan="2" col="2" groups="base.group_extended">
|
||||
<separator string="Advanced Options" colspan="2"/>
|
||||
<field name="mail_server_id"/>
|
||||
<field name="track_campaign_item" colspan="4"/>
|
||||
<field name="message_id"/>
|
||||
<field name="auto_delete"/>
|
||||
</group>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Attachments" colspan="2"/>
|
||||
<notebook>
|
||||
<page string="Existing files">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1" height="350"/>
|
||||
</page>
|
||||
<page string="Report">
|
||||
<page string="Attach Report">
|
||||
<field name="report_template" colspan="4"
|
||||
domain="[('model','=',model_int_name)]" />
|
||||
<field name="file_name" colspan="4" />
|
||||
domain="[('model','=',model)]"/>
|
||||
<field name="report_name" colspan="4" />
|
||||
</page>
|
||||
<page string="Attach existing files">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1" height="350"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
|
@ -150,16 +108,13 @@
|
|||
<field name="model">email.template</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Email Templates">
|
||||
<tree string="Templates">
|
||||
<field name="model_id"/>
|
||||
<field name="name"/>
|
||||
<field name="from_account"/>
|
||||
<field name="object_name"/>
|
||||
<field name="def_to"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
<field name="def_subject"/>
|
||||
<field name="use_sign"/>
|
||||
<field name="file_name"/>
|
||||
<field name="subject"/>
|
||||
<field name="email_from"/>
|
||||
<field name="email_to"/>
|
||||
<field name="report_name"/>
|
||||
<button name="%(wizard_email_template_preview)d" string="Preview Template"
|
||||
type="action" target="new" icon="gtk-zoom-fit"/>
|
||||
</tree>
|
||||
|
@ -173,26 +128,26 @@
|
|||
<field name="arch" type="xml">
|
||||
<search string="Templates">
|
||||
<group col="13" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="object_name" select="1"/>
|
||||
<field name="def_to" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="email_to"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="lang" select="1"/>
|
||||
<field name="def_subject" select="1"/>
|
||||
<field name="file_name" select="1"/>
|
||||
<field name="lang"/>
|
||||
<field name="subject"/>
|
||||
<field name="report_name"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Group by..." colspan="4" col="10">
|
||||
<filter string="Account" domain="[]" context="{'group_by':'from_account'}" icon="terp-folder-orange"/>
|
||||
<filter string="SMTP Server" domain="[]" context="{'group_by':'smtp_server_id'}" icon="terp-folder-orange"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Resource" domain="[]" context="{'group_by':'object_name'}" icon="terp-accessories-archiver"/>
|
||||
<filter string="Model" domain="[]" context="{'group_by':'model_id'}" icon="terp-accessories-archiver"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_tree_all">
|
||||
<field name="name">Email Templates</field>
|
||||
<field name="name">Templates</field>
|
||||
<field name="res_model">email.template</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
|
@ -200,16 +155,9 @@
|
|||
<field name="search_view_id" ref="view_email_template_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Email Templates" id="menu_email_template_all"
|
||||
parent="menu_email_template" action="action_email_template_tree_all" />
|
||||
<menuitem name="Templates" id="menu_email_template_all_tools"
|
||||
parent="mail.menu_email_message_tools" action="action_email_template_tree_all" />
|
||||
|
||||
|
||||
<!-- Email Template menu in Tools -->
|
||||
<menuitem name="Email Templates" id="menu_email_template_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_tree_all" />
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="wkf_email_template_setting" model="workflow">
|
||||
<field name="name">Email Template Workflow</field>
|
||||
<field name="osv">email_template.account</field>
|
||||
<field name="on_create">True</field>
|
||||
</record>
|
||||
|
||||
<!--Activity -->
|
||||
|
||||
<record id="act_draft" model="workflow.activity">
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="flow_start">True</field>
|
||||
<field name="name">draft</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state':'draft'})</field>
|
||||
</record>
|
||||
|
||||
<record id="act_approved" model="workflow.activity">
|
||||
<field name="name">approval</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">do_approval()</field>
|
||||
</record>
|
||||
|
||||
<record id="act_suspended" model="workflow.activity">
|
||||
<field name="name">suspended</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state':'suspended'})</field>
|
||||
</record>
|
||||
<record id="act_dummy" model="workflow.activity">
|
||||
<field name="name">dummy</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="flow_stop">True</field>
|
||||
</record>
|
||||
|
||||
<!-- Transition -->
|
||||
|
||||
<record id="trans_awaiting_approved" model="workflow.transition">
|
||||
<field name="act_from" ref="act_draft"/>
|
||||
<field name="act_to" ref="act_approved"/>
|
||||
<field name="signal">button_approval</field>
|
||||
</record>
|
||||
|
||||
<record id="trans_approved_suspended" model="workflow.transition">
|
||||
<field name="act_from" ref="act_approved"/>
|
||||
<field name="act_to" ref="act_suspended"/>
|
||||
<field name="signal">button_suspended</field>
|
||||
</record>
|
||||
<record id="trans_suspended_reapproved" model="workflow.transition">
|
||||
<field name="act_from" ref="act_suspended"/>
|
||||
<field name="act_to" ref="act_draft"/>
|
||||
<field name="signal">get_reapprove</field>
|
||||
</record>
|
||||
<record id="trans_suspended_dummy" model="workflow.transition">
|
||||
<field name="act_from" ref="act_suspended"/>
|
||||
<field name="act_to" ref="act_dummy"/>
|
||||
<field name="signal">get_never</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="0">
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,10 +1,4 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_email_template_account","email_template.account","model_email_template_account","marketing.group_marketing_user",1,0,0,0
|
||||
"access_email_template","email.template","model_email_template","marketing.group_marketing_user",1,0,0,0
|
||||
"access_email_template_mailbox","email_template.mailbox","model_email_template_mailbox","marketing.group_marketing_user",1,1,1,1
|
||||
"access_email_template_account_system","email_template.account system","model_email_template_account","base.group_system",1,1,1,1
|
||||
"access_email_template","email.template","model_email_template",,1,0,0,0
|
||||
"access_email_template_system","email.template system","model_email_template","base.group_system",1,1,1,1
|
||||
"access_email_template_mailbox_system","email_template.mailbox system","model_email_template_mailbox","base.group_system",1,0,0,0
|
||||
"access_email_template_account_manager","email_template.account","model_email_template_account","marketing.group_marketing_manager",1,1,1,1
|
||||
"access_email_template_manager","email.template","model_email_template","marketing.group_marketing_manager",1,1,1,1
|
||||
"access_email_template_mailbox_manager","email_template.mailbox","model_email_template_mailbox","marketing.group_marketing_manager",1,1,1,1
|
||||
"access_email_template_manager","email.template","model_email_template",,1,1,1,1
|
||||
|
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
# Copyright (C) 2010-Today 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 General Public License as published by
|
||||
|
@ -19,5 +19,6 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
import email_template_preview
|
||||
import mail_compose_message
|
||||
|
||||
import email_template_send_wizard
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="email_compose_message_wizard_inherit_form">
|
||||
<field name="name">mail.compose.message.form</field>
|
||||
<field name="model">mail.compose.message</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//label[@name='placeholder']" position="before">
|
||||
<group attrs="{'invisible':[('use_template','=',False)]}" colspan="4" col="4">
|
||||
<field name="template_id" colspan="3"
|
||||
on_change="on_change_template(use_template, template_id, email_from, email_to, context)"/>
|
||||
<label string="" name="flexspace" colspan="1"/>
|
||||
</group>
|
||||
<group colspan="1" col="6">
|
||||
<field name="use_template" invisible="1"/>
|
||||
<button icon="gtk-paste" type="object" name="template_toggle"
|
||||
string="" help="Use a message template" colspan="1"/>
|
||||
<button icon="gtk-save" type="object" name="save_as_template"
|
||||
string="" help="Save as a new template" colspan="1"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,93 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-Today 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
|
||||
class email_template_preview(osv.osv_memory):
|
||||
_inherit = "email.template"
|
||||
_name = "email_template.preview"
|
||||
_description = "Email Template Preview"
|
||||
_rec_name = "subject"
|
||||
|
||||
def _get_records(self, cr, uid, context=None):
|
||||
"""
|
||||
Return Records of particular Email Template's Model
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
template_id = context.get('template_id', False)
|
||||
if not template_id:
|
||||
return []
|
||||
email_template = self.pool.get('email.template')
|
||||
template = email_template.browse(cr, uid, int(template_id), context=context)
|
||||
template_object = template.model_id
|
||||
model = self.pool.get(template_object.model)
|
||||
record_ids = model.search(cr, uid, [], 0, 10, 'id', context=context)
|
||||
default_id = context.get('default_res_id')
|
||||
|
||||
if default_id and default_id not in record_ids:
|
||||
record_ids.insert(0, default_id)
|
||||
|
||||
return model.name_get(cr, uid, record_ids, context)
|
||||
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_preview, self).default_get(cr, uid, fields, context=context)
|
||||
|
||||
email_template = self.pool.get('email.template')
|
||||
template_id = context.get('template_id')
|
||||
if 'res_id' in fields and not result.get('res_id'):
|
||||
records = self._get_records(cr, uid, context=context)
|
||||
result['res_id'] = records and records[0][0] or False # select first record as a Default
|
||||
if template_id and 'model_id' in fields and not result.get('model_id'):
|
||||
result['model_id'] = email_template.read(cr, uid, int(template_id), ['model_id'], context).get('model_id', False)
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'res_id':fields.selection(_get_records, 'Sample Document'),
|
||||
}
|
||||
|
||||
def on_change_res_id(self, cr, uid, ids, res_id, context=None):
|
||||
if not res_id:
|
||||
return {}
|
||||
vals = {}
|
||||
email_template = self.pool.get('email.template')
|
||||
template_id = context and context.get('template_id')
|
||||
template = email_template.get_email_template(cr, uid, template_id=template_id, record_id=res_id, context=context)
|
||||
model = template.model
|
||||
vals['email_to'] = self.render_template(cr, uid, template.email_to, model, res_id, context)
|
||||
vals['email_cc'] = self.render_template(cr, uid, template.email_cc, model, res_id, context)
|
||||
vals['email_bcc'] = self.render_template(cr, uid, template.email_bcc, model, res_id, context)
|
||||
vals['reply_to'] = self.render_template(cr, uid, template.reply_to, model, res_id, context)
|
||||
vals['subject'] = self.render_template(cr, uid, template.subject, model, res_id, context)
|
||||
description = self.render_template(cr, uid, template.body_text, model, res_id, context) or ''
|
||||
if template.user_signature:
|
||||
signature = self.pool.get('res.users').browse(cr, uid, uid, context).signature
|
||||
description += '\n' + signature
|
||||
vals['body_text'] = description
|
||||
vals['report_name'] = self.render_template(cr, uid, template.report_name, model, res_id, context)
|
||||
return {'value': vals}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Email Template Preview -->
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="name">email_template.preview.form</field>
|
||||
<field name="model">email_template.preview</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Preview">
|
||||
<field name="model_id" invisible="1"/>
|
||||
<field name="res_id" on_change="on_change_res_id(res_id, context)"/>
|
||||
<group col="2" colspan="4">
|
||||
<field name="email_to" readonly="1"/>
|
||||
<field name="email_cc" readonly="1" attrs="{'invisible': [('email_cc','=',False)]}"/>
|
||||
<field name="email_bcc" readonly="1" attrs="{'invisible': [('email_bcc','=',False)]}"/>
|
||||
<field name="reply_to" readonly="1" attrs="{'invisible': [('reply_to','=',False)]}"/>
|
||||
<field name="subject" readonly="1"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<notebook>
|
||||
<page string="Body (Text)">
|
||||
<field name="body_text" nolabel="1" colspan="4" height="350" width="350" readonly="1"/>
|
||||
</page>
|
||||
<page string="Body (Rich/HTML)" attrs="{'invisible': [('body_html','=', False)]}">
|
||||
<field name="body_html" nolabel="1" colspan="4" height="350" width="350" readonly="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
<field name="report_name" colspan="4" readonly="1"/>
|
||||
<separator colspan="4"/>
|
||||
<group col="4" colspan="4">
|
||||
<label string=""/>
|
||||
<button icon="gtk-ok" special="cancel" string="Close" colspan="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="wizard_email_template_preview" model="ir.actions.act_window">
|
||||
<field name="name">Template Preview</field>
|
||||
<field name="res_model">email_template.preview</field>
|
||||
<field name="src_model">email_template.preview</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="auto_refresh" eval="1" />
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'template_id':active_id}</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,279 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
from mako.template import Template
|
||||
from mako import exceptions
|
||||
import netsvc
|
||||
import base64
|
||||
from tools.translate import _
|
||||
import tools
|
||||
from email_template.email_template import get_value
|
||||
|
||||
|
||||
## FIXME: this wizard duplicates a lot of features of the email template preview,
|
||||
## one of the 2 should inherit from the other!
|
||||
|
||||
class email_template_send_wizard(osv.osv_memory):
|
||||
_name = 'email_template.send.wizard'
|
||||
_description = 'This is the wizard for sending mail'
|
||||
_rec_name = "subject"
|
||||
|
||||
def _get_accounts(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
template = self._get_template(cr, uid, context)
|
||||
if not template:
|
||||
return []
|
||||
|
||||
logger = netsvc.Logger()
|
||||
|
||||
if template.from_account:
|
||||
return [(template.from_account.id, '%s (%s)' % (template.from_account.name, template.from_account.email_id))]
|
||||
else:
|
||||
account_id = self.pool.get('email_template.account').search(cr,uid,[('company','=','no'),('user','=',uid)], context=context)
|
||||
if account_id:
|
||||
account = self.pool.get('email_template.account').browse(cr,uid,account_id, context)
|
||||
return [(r.id,r.name + " (" + r.email_id + ")") for r in account]
|
||||
else:
|
||||
logger.notifyChannel(_("email-template"), netsvc.LOG_ERROR, _("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal email account."))
|
||||
raise osv.except_osv(_("Missing mail account"),_("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal email account."))
|
||||
|
||||
def get_value(self, cursor, user, template, message, context=None, id=None):
|
||||
"""Gets the value of the message parsed with the content of object id (or the first 'src_rec_ids' if id is not given)"""
|
||||
if not message:
|
||||
return ''
|
||||
if not id:
|
||||
id = context['src_rec_ids'][0]
|
||||
return get_value(cursor, user, id, message, template, context)
|
||||
|
||||
def _get_template(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not 'template' in context and not 'template_id' in context:
|
||||
return None
|
||||
if 'template_id' in context.keys():
|
||||
template_ids = self.pool.get('email.template').search(cr, uid, [('id','=',context['template_id'])], context=context)
|
||||
elif 'template' in context.keys():
|
||||
# Old versions of email_template used the name of the template. This caused
|
||||
# problems when the user changed the name of the template, but we keep the code
|
||||
# for compatibility with those versions.
|
||||
template_ids = self.pool.get('email.template').search(cr, uid, [('name','=',context['template'])], context=context)
|
||||
if not template_ids:
|
||||
return None
|
||||
|
||||
template = self.pool.get('email.template').browse(cr, uid, template_ids[0], context)
|
||||
|
||||
lang = self.get_value(cr, uid, template, template.lang, context)
|
||||
if lang:
|
||||
# Use translated template if necessary
|
||||
ctx = context.copy()
|
||||
ctx['lang'] = lang
|
||||
template = self.pool.get('email.template').browse(cr, uid, template.id, ctx)
|
||||
return template
|
||||
|
||||
def _get_template_value(self, cr, uid, field, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
template = self._get_template(cr, uid, context)
|
||||
if not template:
|
||||
return False
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets original template values for multiple email change
|
||||
return getattr(template, field)
|
||||
else: # Simple Mail: Gets computed template values
|
||||
return self.get_value(cr, uid, template, getattr(template, field), context)
|
||||
|
||||
_columns = {
|
||||
'state':fields.selection([
|
||||
('single','Simple Mail Wizard Step 1'),
|
||||
('multi','Multiple Mail Wizard Step 1'),
|
||||
('done','Wizard Complete')
|
||||
],'Status',readonly=True),
|
||||
'ref_template':fields.many2one('email.template','Template',readonly=True),
|
||||
'rel_model':fields.many2one('ir.model','Model',readonly=True),
|
||||
'rel_model_ref':fields.integer('Referred Document',readonly=True),
|
||||
'from':fields.selection(_get_accounts,'From Account',select=True),
|
||||
'to':fields.char('To',size=250,required=True),
|
||||
'cc':fields.char('CC',size=250,),
|
||||
'bcc':fields.char('BCC',size=250,),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'subject':fields.char('Subject',size=200),
|
||||
'body_text':fields.text('Body',),
|
||||
'body_html':fields.text('Body',),
|
||||
'report':fields.char('Report File Name',size=100,),
|
||||
'signature':fields.boolean('Attach my signature to mail'),
|
||||
#'filename':fields.text('File Name'),
|
||||
'requested':fields.integer('No of requested Mails',readonly=True),
|
||||
'generated':fields.integer('No of generated Mails',readonly=True),
|
||||
'full_success':fields.boolean('Complete Success',readonly=True),
|
||||
'attachment_ids': fields.many2many('ir.attachment','send_wizard_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
|
||||
}
|
||||
|
||||
#FIXME: probably better by overriding default_get directly
|
||||
_defaults = {
|
||||
'state': lambda self,cr,uid,ctx: len(ctx['src_rec_ids']) > 1 and 'multi' or 'single',
|
||||
'rel_model': lambda self,cr,uid,ctx: self.pool.get('ir.model').search(cr,uid,[('model','=',ctx['src_model'])],context=ctx)[0],
|
||||
'rel_model_ref': lambda self,cr,uid,ctx: ctx['active_id'],
|
||||
'to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_to', ctx),
|
||||
'cc': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_cc', ctx),
|
||||
'bcc': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_bcc', ctx),
|
||||
'subject':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_subject', ctx),
|
||||
'body_text':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_body_text', ctx),
|
||||
'body_html':lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'def_body_html', ctx),
|
||||
'report': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'file_name', ctx),
|
||||
'signature': lambda self,cr,uid,ctx: self._get_template(cr, uid, ctx).use_sign,
|
||||
'ref_template':lambda self,cr,uid,ctx: self._get_template(cr, uid, ctx).id,
|
||||
'reply_to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'reply_to', ctx),
|
||||
'reply_to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'reply_to', ctx),
|
||||
'requested':lambda self,cr,uid,ctx: len(ctx['src_rec_ids']),
|
||||
'full_success': False,
|
||||
'attachment_ids': [],
|
||||
}
|
||||
|
||||
def fields_get(self, cr, uid, fields=None, context=None, write_access=True):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_send_wizard, self).fields_get(cr, uid, fields, context, write_access)
|
||||
if 'attachment_ids' in result and 'src_model' in context:
|
||||
result['attachment_ids']['domain'] = [('res_model','=',context['src_model']),('res_id','=',context['active_id'])]
|
||||
return result
|
||||
|
||||
def sav_to_drafts(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
mailid = self.save_to_mailbox(cr, uid, ids, context=context)
|
||||
if self.pool.get('email_template.mailbox').write(cr, uid, mailid, {'folder':'drafts'}, context):
|
||||
return {'type':'ir.actions.act_window_close' }
|
||||
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
mailid = self.save_to_mailbox(cr, uid, ids, context)
|
||||
if self.pool.get('email_template.mailbox').write(cr, uid, mailid, {'folder':'outbox'}, context):
|
||||
return {'type':'ir.actions.act_window_close' }
|
||||
|
||||
def get_generated(self, cr, uid, ids=None, context=None):
|
||||
if ids is None:
|
||||
ids = []
|
||||
if context is None:
|
||||
context = {}
|
||||
logger = netsvc.Logger()
|
||||
if context['src_rec_ids'] and len(context['src_rec_ids'])>1:
|
||||
#Means there are multiple items selected for email.
|
||||
mail_ids = self.save_to_mailbox(cr, uid, ids, context)
|
||||
if mail_ids:
|
||||
self.pool.get('email_template.mailbox').write(cr, uid, mail_ids, {'folder':'outbox'}, context)
|
||||
logger.notifyChannel("email-template", netsvc.LOG_INFO, _("Emails for multiple items saved in outbox."))
|
||||
self.write(cr, uid, ids, {
|
||||
'generated':len(mail_ids),
|
||||
'state':'done'
|
||||
}, context)
|
||||
else:
|
||||
raise osv.except_osv(_("Email Template"),_("Email sending failed for one or more objects."))
|
||||
return True
|
||||
|
||||
def save_to_mailbox(self, cr, uid, ids, context=None):
|
||||
def get_end_value(id, value):
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets value from the template
|
||||
return self.get_value(cr, uid, template, value, context, id)
|
||||
else:
|
||||
return value
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
mail_ids = []
|
||||
template = self._get_template(cr, uid, context)
|
||||
for id in context['src_rec_ids']:
|
||||
screen_vals = self.read(cr, uid, ids[0], [],context)
|
||||
account = self.pool.get('email_template.account').read(cr, uid, screen_vals['from'], context=context)
|
||||
vals = {
|
||||
'email_from': tools.ustr(account['name']) + "<" + tools.ustr(account['email_id']) + ">",
|
||||
'email_to': get_end_value(id, screen_vals['to']),
|
||||
'email_cc': get_end_value(id, screen_vals['cc']),
|
||||
'email_bcc': get_end_value(id, screen_vals['bcc']),
|
||||
'subject': get_end_value(id, screen_vals['subject']),
|
||||
'body_text': get_end_value(id, screen_vals['body_text']),
|
||||
'body_html': get_end_value(id, screen_vals['body_html']),
|
||||
'account_id': screen_vals['from'],
|
||||
'state':'na',
|
||||
'mail_type':'multipart/alternative' #Options:'multipart/mixed','multipart/alternative','text/plain','text/html'
|
||||
}
|
||||
if screen_vals['signature']:
|
||||
signature = self.pool.get('res.users').read(cr, uid, uid, ['signature'], context)['signature']
|
||||
if signature:
|
||||
vals['body_text'] = tools.ustr(vals['body_text'] or '') + signature
|
||||
vals['body_html'] = tools.ustr(vals['body_html'] or '') + signature
|
||||
|
||||
attachment_ids = []
|
||||
|
||||
#Create partly the mail and later update attachments
|
||||
mail_id = self.pool.get('email_template.mailbox').create(cr, uid, vals, context)
|
||||
mail_ids.append(mail_id)
|
||||
if template.report_template:
|
||||
reportname = 'report.' + self.pool.get('ir.actions.report.xml').read(cr, uid, template.report_template.id, ['report_name'], context)['report_name']
|
||||
data = {}
|
||||
data['model'] = self.pool.get('ir.model').browse(cr, uid, screen_vals['rel_model'], context).model
|
||||
|
||||
# Ensure report is rendered using template's language
|
||||
ctx = context.copy()
|
||||
if template.lang:
|
||||
ctx['lang'] = self.get_value(cr, uid, template, template.lang, context, id)
|
||||
service = netsvc.LocalService(reportname)
|
||||
(result, format) = service.create(cr, uid, [id], data, ctx)
|
||||
attachment_id = self.pool.get('ir.attachment').create(cr, uid, {
|
||||
'name': _('%s (Email Attachment)') % tools.ustr(vals['subject']),
|
||||
'datas': base64.b64encode(result),
|
||||
'datas_fname': tools.ustr(get_end_value(id, screen_vals['report']) or _('Report')) + "." + format,
|
||||
'description': vals['body_text'] or _("No Description"),
|
||||
'res_model': 'email_template.mailbox',
|
||||
'res_id': mail_id
|
||||
}, context)
|
||||
attachment_ids.append( attachment_id )
|
||||
|
||||
# Add document attachments
|
||||
for attachment_id in screen_vals.get('attachment_ids',[]):
|
||||
new_id = self.pool.get('ir.attachment').copy(cr, uid, attachment_id, {
|
||||
'res_model': 'email_template.mailbox',
|
||||
'res_id': mail_id,
|
||||
}, context)
|
||||
attachment_ids.append( new_id )
|
||||
|
||||
if attachment_ids:
|
||||
self.pool.get('email_template.mailbox').write(cr, uid, mail_id, {
|
||||
'attachments_ids': [[6, 0, attachment_ids]],
|
||||
'mail_type': 'multipart/mixed'
|
||||
}, context)
|
||||
|
||||
return mail_ids
|
||||
email_template_send_wizard()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,63 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_send_wizard_form">
|
||||
<field name="name">email_template.send.wizard.form</field>
|
||||
<field name="model">email_template.send.wizard</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Send mail Wizard">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model" colspan="2" />
|
||||
<field name="from" required="1" colspan="2" />
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<group col="6" colspan="4">
|
||||
<field name="to" select="1" colspan="4" />
|
||||
<newline />
|
||||
<field name="cc" select="2" colspan="4" />
|
||||
<newline />
|
||||
<field name="bcc" select="2" colspan="4" />
|
||||
<newline />
|
||||
<field name="subject" select="2" colspan="4" attrs="{'required':[('state','=','single')]}" />
|
||||
<newline />
|
||||
<field name="report" colspan="4" />
|
||||
</group>
|
||||
<separator string="" colspan="4" />
|
||||
<notebook colspan="4">
|
||||
<page string="Body (Plain Text)">
|
||||
<field name="body_text" select="2" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Body (HTML)">
|
||||
<field name="body_html" select="2" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<label string="Add here all attachments of the current document you want to include in the Email." colspan="4"/>
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="signature" colspan="4" />
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('state','!=','single')]}">
|
||||
<button icon="gtk-apply" name="sav_to_drafts" string="Save in Drafts" type="object" />
|
||||
<button icon="gtk-ok" name="send_mail" string="Send now" type="object" />
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard Mail" />
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('state','=','single')]}">
|
||||
<label string="Tip: Multiple emails are sent in the same language (the first one is proposed). We suggest you send emails in groups according to language." colspan="4"/>
|
||||
<field name="requested" />
|
||||
<field name="generated" />
|
||||
<button icon="gtk-ok" name="get_generated" string="Send all mails" type="object" states="multi" colspan="2" />
|
||||
<button icon="gtk-cancel" special="cancel" string="Discard Mail" colspan="2" states="multi" />
|
||||
</group>
|
||||
<button icon="gtk-ok" special="cancel" string="Close" colspan="4" states="done" />
|
||||
<field name="state" />
|
||||
<newline />
|
||||
<label string="After clicking send all mails, mails will be sent to outbox and cleared in next Send/Recieve" colspan="4"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2010-Today 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import base64
|
||||
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
||||
|
||||
def _reopen(self,res_id,model):
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'view_type': 'form',
|
||||
'res_id': res_id,
|
||||
'res_model': self._name,
|
||||
'target': 'new',
|
||||
|
||||
# save original model in context, otherwise
|
||||
# it will be lost on the action's context switch
|
||||
'mail.compose.target.model': model,
|
||||
}
|
||||
|
||||
class mail_compose_message(osv.osv_memory):
|
||||
_inherit = 'mail.compose.message'
|
||||
|
||||
def _get_templates(self, cr, uid, context=None):
|
||||
"""
|
||||
Return Email Template of particular Model.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
record_ids = []
|
||||
email_template= self.pool.get('email.template')
|
||||
model = False
|
||||
if context.get('message_id'):
|
||||
mail_message = self.pool.get('mail.message')
|
||||
message_data = mail_message.browse(cr, uid, int(context.get('message_id')), context)
|
||||
model = message_data.model
|
||||
elif context.get('mail.compose.target.model') or context.get('active_model'):
|
||||
model = context.get('mail.compose.target.model', context.get('active_model'))
|
||||
if model:
|
||||
record_ids = email_template.search(cr, uid, [('model', '=', model)])
|
||||
return email_template.name_get(cr, uid, record_ids, context) + [(False,'')]
|
||||
return []
|
||||
|
||||
_columns = {
|
||||
'use_template': fields.boolean('Use Template'),
|
||||
'template_id': fields.selection(_get_templates, 'Template'),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, use_template, template_id, email_from=None, email_to=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
values = {}
|
||||
if template_id:
|
||||
res_id = context.get('active_id', False)
|
||||
if context.get('mail.compose.message.mode') == 'mass_mail':
|
||||
# use the original template values - to be rendered when actually sent
|
||||
# by super.send_mail()
|
||||
values = self.pool.get('email.template').read(cr, uid, template_id, self.fields_get_keys(cr, uid), context)
|
||||
else:
|
||||
# render the mail as one-shot
|
||||
values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
|
||||
# retrofit generated attachments in the expected field format
|
||||
if values['attachments']:
|
||||
attachment = values.pop('attachments')
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
att_ids = []
|
||||
for fname, fcontent in attachment.iteritems():
|
||||
data_attach = {
|
||||
'name': fname,
|
||||
'datas': base64.b64encode(fcontent),
|
||||
'datas_fname': fname,
|
||||
'description': fname,
|
||||
'res_model' : self._name,
|
||||
'res_id' : ids[0] if ids else False
|
||||
}
|
||||
att_ids.append(attachment_obj.create(cr, uid, data_attach))
|
||||
values['attachment_ids'] = att_ids
|
||||
else:
|
||||
# restore defaults
|
||||
values = self.default_get(cr, uid, self.fields_get_keys(cr, uid), context)
|
||||
values.update(use_template=use_template, template_id=template_id)
|
||||
|
||||
return {'value': values}
|
||||
|
||||
|
||||
def template_toggle(self, cr, uid, ids, context=None):
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
had_template = record.use_template
|
||||
record.write({'use_template': not(had_template)})
|
||||
if had_template:
|
||||
# equivalent to choosing an empty template
|
||||
onchange_defaults = self.on_change_template(cr, uid, record.id, not(had_template),
|
||||
False, email_from=record.email_from,
|
||||
email_to=record.email_to, context=context)
|
||||
record.write(onchange_defaults['value'])
|
||||
return _reopen(self, record.id, record.model)
|
||||
|
||||
def save_as_template(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
email_template = self.pool.get('email.template')
|
||||
model_pool = self.pool.get('ir.model')
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
model = record.model or context.get('active_model')
|
||||
model_ids = model_pool.search(cr, uid, [('model', '=', model)])
|
||||
model_id = model_ids and model_ids[0] or False
|
||||
model_name = ''
|
||||
if model_id:
|
||||
model_name = model_pool.browse(cr, uid, model_id, context=context).name
|
||||
template_name = "%s: %s" % (model_name, tools.ustr(record.subject))
|
||||
values = {
|
||||
'name': template_name,
|
||||
'email_from': record.email_from or False,
|
||||
'subject': record.subject or False,
|
||||
'body_text': record.body_text or False,
|
||||
'email_to': record.email_to or False,
|
||||
'email_cc': record.email_cc or False,
|
||||
'email_bcc': record.email_bcc or False,
|
||||
'reply_to': record.reply_to or False,
|
||||
'model_id': model_id or False,
|
||||
'attachment_ids': [(6, 0, [att.id for att in record.attachment_ids])]
|
||||
}
|
||||
template_id = email_template.create(cr, uid, values, context=context)
|
||||
record.write({'template_id': template_id,
|
||||
'use_template': True})
|
||||
|
||||
# _reopen same wizard screen with new template preselected
|
||||
return _reopen(self, record.id, model)
|
||||
|
||||
# override the basic implementation
|
||||
def render_template(self, cr, uid, template, model, res_id, context=None):
|
||||
return self.pool.get('email.template').render_template(cr, uid, template, model, res_id, context=context)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -29,7 +29,7 @@
|
|||
Organization and management of Events.
|
||||
======================================
|
||||
|
||||
This module allow you
|
||||
This module allows you
|
||||
* to manage your events and their registrations
|
||||
* to use emails to automatically confirm and send acknowledgements for any registration to an event
|
||||
* ...
|
||||
|
@ -39,7 +39,7 @@ Note that:
|
|||
Association / Configuration / Types of Events
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['crm', 'base_contact', 'account', 'marketing'],
|
||||
'depends': ['crm', 'base_contact', 'account', 'marketing', 'mail'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
'security/event_security.xml',
|
||||
|
|
|
@ -24,8 +24,11 @@ import time
|
|||
from crm import crm
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import tools
|
||||
import decimal_precision as dp
|
||||
from crm import wizard
|
||||
|
||||
|
||||
wizard.mail_compose_message.SUPPORTED_MODELS.append('event.registration')
|
||||
|
||||
class event_type(osv.osv):
|
||||
""" Event Type """
|
||||
|
@ -280,7 +283,7 @@ class event_registration(osv.osv):
|
|||
"""Event Registration"""
|
||||
_name= 'event.registration'
|
||||
_description = __doc__
|
||||
_inherit = 'mailgate.thread'
|
||||
_inherit = 'mail.thread'
|
||||
|
||||
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
|
@ -313,8 +316,8 @@ class event_registration(osv.osv):
|
|||
'create_date': fields.datetime('Creation Date', readonly=True),
|
||||
'write_date': fields.datetime('Write Date', readonly=True),
|
||||
'description': fields.text('Description', states={'done': [('readonly', True)]}),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
|
||||
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'log_ids': fields.one2many('mail.message', 'res_id', 'Logs', domain=[('email_from', '=', False),('model','=',_name)]),
|
||||
'date_deadline': fields.related('event_id','date_end', type='datetime', string="End Date", readonly=True),
|
||||
'date': fields.related('event_id', 'date_begin', type='datetime', string="Start Date", readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
||||
|
@ -354,7 +357,7 @@ class event_registration(osv.osv):
|
|||
})
|
||||
inv_id = inv_pool.create(cr, uid, val_invoice['value'], context=context)
|
||||
inv_pool.button_compute(cr, uid, [inv_id])
|
||||
self.history(cr, uid, [reg], _('Invoiced'))
|
||||
self.message_append(cr, uid, [reg], _('Invoiced'))
|
||||
return inv_id
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -429,7 +432,7 @@ class event_registration(osv.osv):
|
|||
"""
|
||||
res = self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
||||
self.mail_user(cr, uid, ids)
|
||||
self.history(cr, uid, ids, _('Open'))
|
||||
self.message_append(cr, uid, ids, _('Open'))
|
||||
return res
|
||||
|
||||
def do_close(self, cr, uid, ids, context=None):
|
||||
|
@ -443,7 +446,7 @@ class event_registration(osv.osv):
|
|||
if invoice_id:
|
||||
values['invoice_id'] = invoice_id
|
||||
res = self.write(cr, uid, ids, values)
|
||||
self.history(cr, uid, ids, msg)
|
||||
self.message_append(cr, uid, ids, msg)
|
||||
return res
|
||||
|
||||
def check_confirm(self, cr, uid, ids, context=None):
|
||||
|
@ -514,42 +517,38 @@ class event_registration(osv.osv):
|
|||
"""This Function Cancel Event Registration.
|
||||
"""
|
||||
registrations = self.browse(cr, uid, ids)
|
||||
self.history(cr, uid, registrations, _('Cancel'))
|
||||
self.message_append(cr, uid, registrations, _('Cancel'))
|
||||
return self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
|
||||
def mail_user(self, cr, uid, ids, confirm=False, context=None):
|
||||
"""
|
||||
Send email to user
|
||||
"""
|
||||
|
||||
for regestration in self.browse(cr, uid, ids, context=context):
|
||||
src = regestration.event_id.reply_to or False
|
||||
mail_message = self.pool.get('mail.message')
|
||||
for registration in self.browse(cr, uid, ids, context=context):
|
||||
src = registration.event_id.reply_to or False
|
||||
email_to = []
|
||||
email_cc = []
|
||||
if regestration.email_from:
|
||||
email_to = regestration.email_from
|
||||
if regestration.email_cc:
|
||||
email_cc += [regestration.email_cc]
|
||||
if registration.email_from:
|
||||
email_to = [registration.email_from]
|
||||
if registration.email_cc:
|
||||
email_cc += [registration.email_cc]
|
||||
if not (email_to or email_cc):
|
||||
continue
|
||||
subject = ""
|
||||
body = ""
|
||||
if confirm:
|
||||
subject = _('Auto Confirmation: [%s] %s') %(regestration.id, regestration.name)
|
||||
body = regestration.event_id.mail_confirm
|
||||
elif regestration.event_id.mail_auto_confirm or regestration.event_id.mail_auto_registr:
|
||||
if regestration.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and regestration.event_id.mail_auto_registr:
|
||||
subject = _('Auto Registration: [%s] %s') %(regestration.id, regestration.name)
|
||||
body = regestration.event_id.mail_registr
|
||||
if (regestration.event_id.state in ['confirm', 'running']) and regestration.event_id.mail_auto_confirm:
|
||||
subject = _('Auto Confirmation: [%s] %s') %(regestration.id, regestration.name)
|
||||
body = regestration.event_id.mail_confirm
|
||||
subject = _('Auto Confirmation: [%s] %s') %(registration.id, registration.name)
|
||||
body = registration.event_id.mail_confirm
|
||||
elif registration.event_id.mail_auto_confirm or registration.event_id.mail_auto_registr:
|
||||
if registration.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and registration.event_id.mail_auto_registr:
|
||||
subject = _('Auto Registration: [%s] %s') %(registration.id, registration.name)
|
||||
body = registration.event_id.mail_registr
|
||||
if (registration.event_id.state in ['confirm', 'running']) and registration.event_id.mail_auto_confirm:
|
||||
subject = _('Auto Confirmation: [%s] %s') %(registration.id, registration.name)
|
||||
body = registration.event_id.mail_confirm
|
||||
if subject or body:
|
||||
tools.email_send(src, email_to, subject, body, email_cc=email_cc, openobject_id=regestration.id)
|
||||
self.history(cr, uid, [regestration], subject, history = True, \
|
||||
email=email_to, details=body, \
|
||||
subject=subject, email_from=src, \
|
||||
email_cc=', '.join(email_cc))
|
||||
mail_message.schedule_with_attach(cr, uid, src, email_to, subject, body, model='event.registration', email_cc=email_cc, res_id=registration.id)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -391,12 +391,12 @@
|
|||
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'event.registration', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
<form string="History">
|
||||
<group col="4" colspan="4">
|
||||
|
@ -404,20 +404,18 @@
|
|||
<field name="date"/>
|
||||
<field name="email_to" widget="char" size="512"/>
|
||||
<field name="email_cc" widget="char" size="512"/>
|
||||
<field name="name" colspan="4" widget="char" size="512"/>
|
||||
<field name="history" invisible="1"/>
|
||||
<field name="subject" colspan="4" widget="char" size="512"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group attrs="{'invisible': [('history', '!=', True)]}">
|
||||
<field name="description" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4"
|
||||
string="Reply"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'reply', 'model': 'event.registration', 'include_original' : True}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
<group attrs="{'invisible': [('email_from', '=', False)]}">
|
||||
<field name="body_text" colspan="4" nolabel="1" height="250"/>
|
||||
<button colspan="4" string="Reply"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('history', '=', True)]}">
|
||||
<group attrs="{'invisible': [('email_from', '!=', False)]}">
|
||||
<field name="display_text" colspan="4" nolabel="1" height="250"/>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -427,14 +425,13 @@
|
|||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
<button string="Add Internal Note"
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(crm.action_crm_send_mail)d"
|
||||
context="{'mail':'new', 'model': 'event.registration'}"
|
||||
icon="terp-mail-message-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="model">report.event.registration</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('confirm');gray:state in('done','cancel')" string="Events Analysis">
|
||||
<tree colors="blue:state == 'draft';black:state == 'confirm';gray:state in('done','cancel')" string="Events Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="speaker_id" invisible="1"/>
|
||||
|
|
|
@ -21,19 +21,42 @@
|
|||
##############################################################################
|
||||
|
||||
{
|
||||
"name" : "Fetchmail Server",
|
||||
"name" : "Automated Email Retriever",
|
||||
"version" : "1.0",
|
||||
"depends" : ["base", 'mail_gateway'],
|
||||
"depends" : ["base", 'mail'],
|
||||
"author" : "OpenERP SA",
|
||||
"category": 'Tools',
|
||||
"description": """
|
||||
Fetch email from POP / IMAP servers.
|
||||
====================================
|
||||
Retrieve incoming email on POP / IMAP servers
|
||||
=============================================
|
||||
|
||||
* Supports SSL
|
||||
* Integrated with all modules
|
||||
* Automatically receive email
|
||||
* Email-based record operations (Add, Update)
|
||||
Enter the parameters of your POP/IMAP account(s), and any incoming
|
||||
emails on these accounts will be automatically downloaded into your OpenERP
|
||||
system. All POP3/IMAP-compatible servers are supported, included those
|
||||
that require an encrypted SSL/TLS connection.
|
||||
|
||||
This can be used to easily create email-based workflows for many
|
||||
email-enabled OpenERP documents, such as:
|
||||
|
||||
* CRM Leads/Opportunities
|
||||
* CRM Claims
|
||||
* Project Issues
|
||||
* Project Tasks
|
||||
* Human Resource Recruitments (Applicants)
|
||||
* etc.
|
||||
|
||||
Just install the relevant application, and you can assign any of
|
||||
these document types (Leads, Project Issues, etc.) to your incoming
|
||||
email accounts. New emails will automatically spawn new documents
|
||||
of the chosen type, so it's a snap to create a mailbox-to-OpenERP
|
||||
integration. Even better: these documents directly act as mini
|
||||
conversations synchronized by email. You can reply from within
|
||||
OpenERP, and the answers will automatically be collected when
|
||||
they come back, and attached to the same *conversation* document.
|
||||
|
||||
For more specific needs, you may also assign custom-defined actions
|
||||
(technically: Server Actions) to be triggered for each incoming
|
||||
mail.
|
||||
""",
|
||||
'website': 'http://www.openerp.com',
|
||||
'init_xml': [],
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from imaplib import IMAP4
|
||||
from imaplib import IMAP4_SSL
|
||||
from poplib import POP3
|
||||
|
@ -29,222 +29,200 @@ from poplib import POP3_SSL
|
|||
import netsvc
|
||||
from osv import osv, fields
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
logger = netsvc.Logger()
|
||||
logger = logging.getLogger('fetchmail')
|
||||
|
||||
|
||||
class email_server(osv.osv):
|
||||
|
||||
_name = 'email.server'
|
||||
class fetchmail_server(osv.osv):
|
||||
"""Incoming POP/IMAP mail server account"""
|
||||
_name = 'fetchmail.server'
|
||||
_description = "POP/IMAP Server"
|
||||
_order = 'priority'
|
||||
|
||||
_columns = {
|
||||
'name':fields.char('Name', size=256, required=True, readonly=False),
|
||||
'active':fields.boolean('Active', required=False),
|
||||
'state':fields.selection([
|
||||
('draft', 'Not Confirmed'),
|
||||
('waiting', 'Waiting for Verification'),
|
||||
('done', 'Confirmed'),
|
||||
], 'State', select=True, readonly=True),
|
||||
'server' : fields.char('Server', size=256, required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'server' : fields.char('Server Name', size=256, required=True, readonly=True, help="Hostname or IP of the mail server", states={'draft':[('readonly', False)]}),
|
||||
'port' : fields.integer('Port', required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'type':fields.selection([
|
||||
('pop', 'POP Server'),
|
||||
('imap', 'IMAP Server'),
|
||||
], 'Server Type', select=True, readonly=False),
|
||||
'is_ssl':fields.boolean('SSL ?', required=False),
|
||||
'attach':fields.boolean('Add Attachments ?', required=False, help="Fetches mail with attachments if true."),
|
||||
'date': fields.date('Date', readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'user' : fields.char('User Name', size=256, required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'password' : fields.char('Password', size=1024, invisible=True, required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
], 'Server Type', select=True, required=True, readonly=False),
|
||||
'is_ssl':fields.boolean('SSL/TLS', help="Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP3S=995)"),
|
||||
'attach':fields.boolean('Keep Attachments', help="Whether attachments should be downloaded. "
|
||||
"If not enabled, incoming emails will be stripped of any attachments before being processed"),
|
||||
'original':fields.boolean('Keep Original', help="Whether a full original copy of each email should be kept for reference"
|
||||
"and attached to each processed message. This will usually double the size of your message database."),
|
||||
'date': fields.datetime('Last Fetch Date', readonly=True),
|
||||
'user' : fields.char('Username', size=256, required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'password' : fields.char('Password', size=1024, required=True, readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'note': fields.text('Description'),
|
||||
'action_id':fields.many2one('ir.actions.server', 'Email Server Action', required=False, domain="[('state','=','email')]", help="An Email Server Action. It will be run whenever an e-mail is fetched from server."),
|
||||
'object_id': fields.many2one('ir.model', "Object To Create", required=True, help="Whenever an email arrives, it automatically creates the object of this type with all the information attached."),
|
||||
'priority': fields.integer('Server Priority', readonly=True, states={'draft':[('readonly', False)]}, help="Priority between 0 to 10, select define the order of Processing"),
|
||||
'user_id':fields.many2one('res.users', 'User', required=False, help="This is the user that runs the cron"),
|
||||
'message_ids': fields.one2many('mailgate.message', 'server_id', 'Messages', readonly=True),
|
||||
'action_id':fields.many2one('ir.actions.server', 'Server Action', help="Optional custom server action to trigger for each incoming mail, "
|
||||
"on the record that was created or updated by this mail"),
|
||||
'object_id': fields.many2one('ir.model', "Target document type", required=True, help="Process each incoming mail as part of a conversation "
|
||||
"corresponding to this document type. This will create "
|
||||
"new documents for new conversations, or attach follow-up "
|
||||
"emails to the existing conversations (documents)."),
|
||||
'priority': fields.integer('Server Priority', readonly=True, states={'draft':[('readonly', False)]}, help="Defines the order of processing, "
|
||||
"lower values mean higher priority"),
|
||||
'message_ids': fields.one2many('mail.message', 'fetchmail_server_id', 'Messages', readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'state': lambda *a: "draft",
|
||||
'active': lambda *a: True,
|
||||
'priority': lambda *a: 5,
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
'user_id': lambda self, cr, uid, ctx: uid,
|
||||
'state': "draft",
|
||||
'active': True,
|
||||
'priority': 5,
|
||||
'attach': True,
|
||||
}
|
||||
|
||||
def check_duplicate(self, cr, uid, ids, context=None):
|
||||
# RFC *-* Why this limitation? why not in SQL constraint?
|
||||
vals = self.read(cr, uid, ids, ['user', 'password'], context=context)[0]
|
||||
cr.execute("select count(id) from email_server where user=%s and password=%s", (vals['user'], vals['password']))
|
||||
res = cr.fetchone()
|
||||
if res:
|
||||
if res[0] > 1:
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_model(self, cr, uid, ids, context = None):
|
||||
if context is None:
|
||||
context = {}
|
||||
current_rec = self.read(cr, uid, ids, context)
|
||||
if current_rec:
|
||||
current_rec = current_rec[0]
|
||||
model_name = self.pool.get('ir.model').browse(cr, uid, current_rec.get('object_id')[0]).model
|
||||
model = self.pool.get(model_name)
|
||||
if hasattr(model, 'message_new'):
|
||||
return True
|
||||
return False
|
||||
|
||||
_constraints = [
|
||||
(check_duplicate, 'Warning! Can\'t have duplicate server configuration!', ['user', 'password']),
|
||||
(check_model, 'Warning! Record for selected Model can not be created\nPlease choose valid Model', ['object_id'])
|
||||
]
|
||||
|
||||
def onchange_server_type(self, cr, uid, ids, server_type=False, ssl=False):
|
||||
port = 0
|
||||
if server_type == 'pop':
|
||||
port = ssl and 995 or 110
|
||||
elif server_type == 'imap':
|
||||
port = ssl and 993 or 143
|
||||
|
||||
return {'value':{'port':port}}
|
||||
|
||||
def set_draft(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids , {'state':'draft'})
|
||||
return True
|
||||
|
||||
|
||||
def connect(self, cr, uid, server_id, context=None):
|
||||
if isinstance(server_id, (list,tuple)):
|
||||
server_id = server_id[0]
|
||||
server = self.browse(cr, uid, server_id, context)
|
||||
if server.type == 'imap':
|
||||
if server.is_ssl:
|
||||
connection = IMAP4_SSL(server.server, int(server.port))
|
||||
else:
|
||||
connection = IMAP4(server.server, int(server.port))
|
||||
connection.login(server.user, server.password)
|
||||
elif server.type == 'pop':
|
||||
if server.is_ssl:
|
||||
connection = POP3_SSL(server.server, int(server.port))
|
||||
else:
|
||||
connection = POP3(server.server, int(server.port))
|
||||
#TODO: use this to remove only unread messages
|
||||
#connection.user("recent:"+server.user)
|
||||
connection.user(server.user)
|
||||
connection.pass_(server.password)
|
||||
return connection
|
||||
|
||||
def button_confirm_login(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
for server in self.browse(cr, uid, ids, context=context):
|
||||
logger.notifyChannel(server.type, netsvc.LOG_INFO, 'fetchmail start checking for new emails on %s' % (server.name))
|
||||
context.update({'server_id': server.id, 'server_type': server.type})
|
||||
try:
|
||||
if server.type == 'imap':
|
||||
imap_server = None
|
||||
if server.is_ssl:
|
||||
imap_server = IMAP4_SSL(server.server, int(server.port))
|
||||
else:
|
||||
imap_server = IMAP4(server.server, int(server.port))
|
||||
|
||||
imap_server.login(server.user, server.password)
|
||||
ret_server = imap_server
|
||||
|
||||
elif server.type == 'pop':
|
||||
pop_server = None
|
||||
if server.is_ssl:
|
||||
pop_server = POP3_SSL(server.server, int(server.port))
|
||||
else:
|
||||
pop_server = POP3(server.server, int(server.port))
|
||||
|
||||
#TODO: use this to remove only unread messages
|
||||
#pop_server.user("recent:"+server.user)
|
||||
pop_server.user(server.user)
|
||||
pop_server.pass_(server.password)
|
||||
ret_server = pop_server
|
||||
|
||||
self.write(cr, uid, [server.id], {'state':'done'})
|
||||
if context.get('get_server',False):
|
||||
return ret_server
|
||||
connection = server.connect()
|
||||
server.write({'state':'done'})
|
||||
except Exception, e:
|
||||
logger.notifyChannel(server.type, netsvc.LOG_WARNING, '%s' % (e))
|
||||
return True
|
||||
|
||||
def button_fetch_mail(self, cr, uid, ids, context=None):
|
||||
self.fetch_mail(cr, uid, ids, context=context)
|
||||
logger.exception("Failed to connect to %s server %s", server.type, server.name)
|
||||
raise osv.except_osv(_("Connection test failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e))
|
||||
finally:
|
||||
try:
|
||||
if connection:
|
||||
if server.type == 'imap':
|
||||
connection.close()
|
||||
elif server.type == 'pop':
|
||||
connection.quit()
|
||||
except Exception:
|
||||
# ignored, just a consequence of the previous exception
|
||||
pass
|
||||
return True
|
||||
|
||||
def _fetch_mails(self, cr, uid, ids=False, context=None):
|
||||
if not ids:
|
||||
ids = self.search(cr, uid, [])
|
||||
ids = self.search(cr, uid, [('state','=','done')])
|
||||
return self.fetch_mail(cr, uid, ids, context=context)
|
||||
|
||||
def fetch_mail(self, cr, uid, ids, context=None):
|
||||
"""WARNING: meant for cron usage only - will commit() after each email!"""
|
||||
if context is None:
|
||||
context = {}
|
||||
email_tool = self.pool.get('email.server.tools')
|
||||
mail_thread = self.pool.get('mail.thread')
|
||||
action_pool = self.pool.get('ir.actions.server')
|
||||
context.update({'get_server': True})
|
||||
for server in self.browse(cr, uid, ids, context=context):
|
||||
logger.info('start checking for new emails on %s server %s', server.type, server.name)
|
||||
context.update({'fetchmail_server_id': server.id, 'server_type': server.type})
|
||||
count = 0
|
||||
user = server.user_id.id or uid
|
||||
try:
|
||||
if server.type == 'imap':
|
||||
imap_server = self.button_confirm_login(cr, uid, [server.id], context=context)
|
||||
if server.type == 'imap':
|
||||
try:
|
||||
imap_server = server.connect()
|
||||
imap_server.select()
|
||||
result, data = imap_server.search(None, '(UNSEEN)')
|
||||
for num in data[0].split():
|
||||
result, data = imap_server.fetch(num, '(RFC822)')
|
||||
res_id = email_tool.process_email(cr, user, server.object_id.model, data[0][1], attach=server.attach, context=context)
|
||||
res_id = mail_thread.message_process(cr, uid, server.object_id.model, data[0][1],
|
||||
save_original=server.original,
|
||||
strip_attachments=(not server.attach),
|
||||
context=context)
|
||||
if res_id and server.action_id:
|
||||
action_pool.run(cr, user, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
|
||||
|
||||
action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
|
||||
imap_server.store(num, '+FLAGS', '\\Seen')
|
||||
cr.commit()
|
||||
count += 1
|
||||
logger.notifyChannel('imap', netsvc.LOG_INFO, 'fetchmail fetch/process %s email(s) from %s' % (count, server.name))
|
||||
|
||||
imap_server.close()
|
||||
imap_server.logout()
|
||||
elif server.type == 'pop':
|
||||
pop_server = self.button_confirm_login(cr, uid, [server.id], context=context)
|
||||
pop_server.list()
|
||||
logger.info("fetched/processed %s email(s) on %s server %s", count, server.type, server.name)
|
||||
except Exception, e:
|
||||
logger.exception("Failed to fetch mail from %s server %s", server.type, server.name)
|
||||
finally:
|
||||
if imap_server:
|
||||
imap_server.close()
|
||||
imap_server.logout()
|
||||
elif server.type == 'pop':
|
||||
try:
|
||||
pop_server = server.connect()
|
||||
(numMsgs, totalSize) = pop_server.stat()
|
||||
pop_server.list()
|
||||
for num in range(1, numMsgs + 1):
|
||||
(header, msges, octets) = pop_server.retr(num)
|
||||
msg = '\n'.join(msges)
|
||||
res_id = email_tool.process_email(cr, user, server.object_id.model, msg, attach=server.attach, context=context)
|
||||
res_id = mail_thread.message_process(cr, uid, server.object_id.model,
|
||||
msg,
|
||||
save_original=server.original,
|
||||
strip_attachments=(not server.attach),
|
||||
context=context)
|
||||
if res_id and server.action_id:
|
||||
action_pool.run(cr, user, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
|
||||
|
||||
action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
|
||||
pop_server.dele(num)
|
||||
|
||||
pop_server.quit()
|
||||
|
||||
logger.notifyChannel(server.type, netsvc.LOG_INFO, 'fetchmail fetch %s email(s) from %s' % (numMsgs, server.name))
|
||||
|
||||
except Exception, e:
|
||||
logger.notifyChannel(server.type, netsvc.LOG_WARNING, '%s' % (tools.ustr(e)))
|
||||
|
||||
cr.commit()
|
||||
logger.info("fetched/processed %s email(s) on %s server %s", numMsgs, server.type, server.name)
|
||||
except Exception, e:
|
||||
logger.exception("Failed to fetch mail from %s server %s", server.type, server.name)
|
||||
finally:
|
||||
if pop_server:
|
||||
pop_server.quit()
|
||||
server.write({'date': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)})
|
||||
return True
|
||||
|
||||
email_server()
|
||||
|
||||
class mailgate_message(osv.osv):
|
||||
|
||||
_inherit = "mailgate.message"
|
||||
|
||||
class mail_message(osv.osv):
|
||||
_inherit = "mail.message"
|
||||
_columns = {
|
||||
'server_id': fields.many2one('email.server', "Mail Server", readonly=True, select=True),
|
||||
'server_type':fields.selection([
|
||||
('pop', 'POP Server'),
|
||||
('imap', 'IMAP Server'),
|
||||
], 'Server Type', select=True, readonly=True),
|
||||
'fetchmail_server_id': fields.many2one('fetchmail.server', "Inbound Mail Server",
|
||||
readonly=True,
|
||||
select=True,
|
||||
oldname='server_id'),
|
||||
}
|
||||
_order = 'id desc'
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if context is None:
|
||||
context={}
|
||||
server_id = context.get('server_id',False)
|
||||
server_type = context.get('server_type',False)
|
||||
if server_id:
|
||||
values['server_id'] = server_id
|
||||
if server_type:
|
||||
values['server_type'] = server_type
|
||||
res = super(mailgate_message,self).create(cr, uid, values, context=context)
|
||||
fetchmail_server_id = context.get('fetchmail_server_id')
|
||||
if fetchmail_server_id:
|
||||
values['fetchmail_server_id'] = fetchmail_server_id
|
||||
res = super(mail_message,self).create(cr, uid, values, context=context)
|
||||
return res
|
||||
|
||||
def write(self, cr, uid, ids, values, context=None):
|
||||
if context is None:
|
||||
context={}
|
||||
server_id = context.get('server_id',False)
|
||||
server_type = context.get('server_type',False)
|
||||
if server_id:
|
||||
values['server_id'] = server_id
|
||||
if server_type:
|
||||
values['server_type'] = server_type
|
||||
res = super(mailgate_message,self).write(cr, uid, ids, values, context=context)
|
||||
fetchmail_server_id = context.get('fetchmail_server_id')
|
||||
if fetchmail_server_id:
|
||||
values['fetchmail_server_id'] = server_id
|
||||
res = super(mail_message,self).write(cr, uid, ids, values, context=context)
|
||||
return res
|
||||
|
||||
mailgate_message()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
<field name="interval_number">5</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
<field eval="'email.server'" name="model"/>
|
||||
<field eval="'_fetch_mails'" name="function"/>
|
||||
<field eval="'()'" name="args"/>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="function">_fetch_mails</field>
|
||||
<field name="args">()</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<record model="ir.actions.act_window" id="view_email_server_form_installer">
|
||||
<field name="name">Setup Your Mail server</field>
|
||||
<field name="name">Setup Incoming Mail Server (fetchmail)</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">email.server</field>
|
||||
<field name="res_model">fetchmail.server</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="fetchmail.view_email_server_form"/>
|
||||
|
|
|
@ -1,44 +1,42 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_email_server_tree">
|
||||
<field name="name">email.server.tree</field>
|
||||
<field name="model">email.server</field>
|
||||
<field name="name">fetchmail.server.list</field>
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('waiting');gray:state in('done')" string="POP/IMAP Servers">
|
||||
<tree colors="blue:state == 'draft'" string="POP/IMAP Servers">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="user"/>
|
||||
<field name="is_ssl"/>
|
||||
<field name="object_id"/>
|
||||
<field name="date"/>
|
||||
<field name="message_ids" string="# of emails"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_email_server_form">
|
||||
<field name="name">email.server.form</field>
|
||||
<field name="model">email.server</field>
|
||||
<field name="name">fetchmail.server.form</field>
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="POP/IMAP Server">
|
||||
<form string="Incoming Mail Server">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1" colspan="4"/>
|
||||
<field name="type" select="1" on_change="onchange_server_type(type, is_ssl)"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="attach"/>
|
||||
<field name="active" select="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Server & Login">
|
||||
<group col="2" colspan="2">
|
||||
<group col="4" colspan="2">
|
||||
<separator string="Server Information" colspan="2"/>
|
||||
<field name="is_ssl" select="1" on_change="onchange_server_type(type, is_ssl)"/>
|
||||
<field name="server" />
|
||||
<field name="server" colspan="4"/>
|
||||
<field name="port" />
|
||||
<field name="is_ssl" select="1" on_change="onchange_server_type(type, is_ssl)"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Login Information" colspan="2"/>
|
||||
|
@ -46,35 +44,39 @@
|
|||
<field name="password" password="True" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Auto Reply?" colspan="2"/>
|
||||
<field name="action_id"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Process Parameter" colspan="2"/>
|
||||
<separator string="Automated Processing" colspan="2"/>
|
||||
<field name="object_id"/>
|
||||
<field name="priority"/>
|
||||
<field name="action_id"/>
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="note" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Advanced options" colspan="2"/>
|
||||
<field name="priority"/>
|
||||
<field name="attach"/>
|
||||
<field name="original"/>
|
||||
<field name="active" select="1"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="6" colspan="4">
|
||||
<field name="state" select="1"/>
|
||||
<button string="Confirm" type="object" name="button_confirm_login" states="draft" icon="gtk-apply"/>
|
||||
<button string="Fetch Emails" type="object" name="button_fetch_mail" states="done"/>
|
||||
<button string="Set to Draft" type="object" name="set_draft" icon="gtk-convert"/>
|
||||
<button string="Reset Confirmation" type="object" name="set_draft" icon="gtk-convert" states="done"/>
|
||||
<button string="Test & Confirm" type="object" name="button_confirm_login" states="draft" icon="gtk-apply"/>
|
||||
<button string="Fetch Now" type="object" name="fetch_mail" states="done" icon="gtk-network"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_email_server_search">
|
||||
<field name="name">email.server.search</field>
|
||||
<field name="model">email.server</field>
|
||||
<field name="name">fetchmail.server.search</field>
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Email Servers">
|
||||
<search string="Search Incoming Mail Servers">
|
||||
<filter string="IMAP" icon="terp-folder-green" domain="[('type','=','imap')]" help="Server type IMAP."/>
|
||||
<filter string="POP" icon="terp-folder-orange" domain="[('type','=','pop')]" help="Server type POP."/>
|
||||
<separator orientation="vertical"/>
|
||||
|
@ -91,68 +93,52 @@
|
|||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_server_tree">
|
||||
<field name="name">Email Servers</field>
|
||||
<field name="res_model">email.server</field>
|
||||
<field name="name">Incoming Mail Servers</field>
|
||||
<field name="res_model">fetchmail.server</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_email_server_tree"/>
|
||||
<field name="search_view_id" ref="view_email_server_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="base.menu_mail_gateway"
|
||||
<menuitem
|
||||
parent="base.next_id_15"
|
||||
id="menu_action_fetchmail_server_tree"
|
||||
action="action_email_server_tree"
|
||||
name="Email Servers"
|
||||
action="action_email_server_tree"
|
||||
name="Incoming Mail Servers"
|
||||
sequence="40"
|
||||
/>
|
||||
|
||||
<record model="ir.ui.view" id="mailgate_message_tree_view">
|
||||
<field name="name">mailgate.message.tree</field>
|
||||
<field name="model">mailgate.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="inherit_id" ref="mail_gateway.view_mailgate_message_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="server_id" select="1"/>
|
||||
<field name="ref_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="mailgate_message_search_view">
|
||||
<field name="name">mailgate.message.inherit.search</field>
|
||||
<field name="model">mailgate.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="inherit_id" ref="mail_gateway.view_mailgate_message_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/search/field[@name='name']" position="before">
|
||||
<filter string="Emails" name="emails" domain="[('server_id','!=',False)]" icon="terp-mail-message-new"/>
|
||||
<separator orientation="vertical"/>
|
||||
</xpath>
|
||||
<xpath expr="/search/group/filter[@string='Thread']" position="before">
|
||||
<filter string="Mail Server" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'server_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_mail_message_emails" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">mailgate.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_emails': 1}</field>
|
||||
<field name="search_view_id" ref="mailgate_message_search_view"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="base.menu_email_gateway_form"
|
||||
parent="base.menu_mail_gateway" action="action_view_mail_message_emails" />
|
||||
|
||||
<act_window
|
||||
context="{'search_default_server_id': [active_id], 'default_server_id': active_id}"
|
||||
id="act_server_history" name="Emails"
|
||||
res_model="mailgate.message" src_model="email.server"/>
|
||||
|
||||
<record model="ir.ui.view" id="email_message_tree_view">
|
||||
<field name="name">mail.message.list.fetchmail</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="inherit_id" ref="mail.view_email_message_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="fetchmail_server_id" select="1"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="email_message_search_view">
|
||||
<field name="name">mail.message.inherit.search</field>
|
||||
<field name="model">mail.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="inherit_id" ref="mail.view_email_message_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/search/group/filter[@string='Thread']" position="before">
|
||||
<filter string="Mail Server" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'fetchmail_server_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
context="{'search_default_server_id': active_id, 'default_server_id': active_id}"
|
||||
id="act_server_history" name="Messages" domain="[('email_from', '!=', False), ('fetchmail_server_id', '=', active_id)]"
|
||||
res_model="mail.message" src_model="fetchmail.server"/>
|
||||
|
||||
</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: 2011-01-11 11:15+0000\n"
|
||||
"PO-Revision-Date: 2011-08-25 11:54+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2011-09-13 09:02+0000\n"
|
||||
"Last-Translator: John Bradshaw <Unknown>\n"
|
||||
"Language-Team: English (United Kingdom) <en_GB@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: 2011-09-05 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 13830)\n"
|
||||
"X-Launchpad-Export-Date: 2011-09-14 04:41+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: fetchmail
|
||||
#: constraint:email.server:0
|
||||
|
@ -105,7 +105,7 @@ msgstr "# of emails"
|
|||
#. module: fetchmail
|
||||
#: model:ir.actions.act_window,name:fetchmail.act_server_history
|
||||
msgid "Email History"
|
||||
msgstr ""
|
||||
msgstr "Email History"
|
||||
|
||||
#. module: fetchmail
|
||||
#: field:email.server,user_id:0
|
||||
|
@ -161,7 +161,7 @@ msgstr "Mail gateway Message"
|
|||
#. module: fetchmail
|
||||
#: model:ir.actions.act_window,name:fetchmail.action_email_server_tree
|
||||
msgid "POP Servers"
|
||||
msgstr ""
|
||||
msgstr "POP Servers"
|
||||
|
||||
#. module: fetchmail
|
||||
#: view:email.server:0
|
||||
|
@ -177,7 +177,7 @@ msgstr "Messages"
|
|||
#. module: fetchmail
|
||||
#: model:ir.ui.menu,name:fetchmail.menu_action_fetchmail_server_tree
|
||||
msgid "Fetchmail Services"
|
||||
msgstr ""
|
||||
msgstr "Fetchmail Services"
|
||||
|
||||
#. module: fetchmail
|
||||
#: field:email.server,server:0
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_email_server","email.server","model_email_server",,1,1,1,1
|
||||
"access_fetchmail_server","fetchmail.server","model_fetchmail_server",,1,0,0,0
|
||||
"access_fetchmail_server","fetchmail.server","model_fetchmail_server","base.group_system",1,1,1,1
|
||||
|
|
|
|
@ -0,0 +1,53 @@
|
|||
# Macedonian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:15+0000\n"
|
||||
"PO-Revision-Date: 2011-09-14 08:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Macedonian <mk@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: 2011-09-15 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 13921)\n"
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
#: view:res.partner.address:0
|
||||
msgid "Map"
|
||||
msgstr "Мапа"
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
#: view:res.partner.address:0
|
||||
msgid "Street2 : "
|
||||
msgstr ""
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.actions.wizard,name:google_map.wizard_google_map
|
||||
msgid "Launch Google Map"
|
||||
msgstr "Стартувај Google Map"
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.module.module,description:google_map.module_meta_information
|
||||
msgid ""
|
||||
"The module adds google map field in partner address\n"
|
||||
"so that we can directly open google map from the\n"
|
||||
"url widget."
|
||||
msgstr ""
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.module.module,shortdesc:google_map.module_meta_information
|
||||
msgid "Google Map"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.model,name:google_map.model_res_partner_address
|
||||
msgid "Partner Addresses"
|
||||
msgstr "Адреса на партнерот"
|
|
@ -197,6 +197,7 @@ class hr_employee(osv.osv):
|
|||
_defaults = {
|
||||
'active': 1,
|
||||
'photo': _get_photo,
|
||||
'marital': 'single',
|
||||
}
|
||||
|
||||
def _check_recursion(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -75,8 +75,8 @@
|
|||
<field name="type_id" widget="selection"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Information">
|
||||
<group col="2" colspan="2">
|
||||
<page string="Information" name="information">
|
||||
<group col="2" colspan="2" name="left_column">
|
||||
<separator colspan="2" string="Duration"/>
|
||||
<field name="date_start" />
|
||||
<field name="date_end" />
|
||||
|
@ -85,7 +85,7 @@
|
|||
<field name="trial_date_start" />
|
||||
<field name="trial_date_end" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<group col="2" colspan="2" name="right_column">
|
||||
<separator name="advantages" colspan="2" string="Advantages"/>
|
||||
<field name="advantages" nolabel="1" colspan="2"/>
|
||||
</group>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue