summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/account/i18n/nl_BE.po27
-rw-r--r--addons/account/report/account_balance.py33
-rw-r--r--addons/account/report/account_balance.rml63
-rw-r--r--addons/account_budget/crossovered_budget_view.xml21
-rw-r--r--addons/account_invoice_layout/account_invoice_layout.py1
-rw-r--r--addons/base_action_rule/base_action_rule_view.xml2
-rw-r--r--addons/base_calendar/base_calendar_view.xml20
-rw-r--r--addons/base_vat/i18n/id.po10
-rw-r--r--addons/crm/crm_phonecall.py1
-rw-r--r--addons/crm_claim/crm_claim_view.xml17
-rw-r--r--addons/crm_fundraising/crm_fundraising_view.xml21
-rw-r--r--addons/crm_helpdesk/crm_helpdesk_view.xml8
-rw-r--r--addons/crm_profiling/crm_profiling_view.xml7
-rwxr-xr-xaddons/email_template/__init__.py5
-rwxr-xr-xaddons/email_template/__openerp__.py24
-rwxr-xr-xaddons/email_template/email_template.py698
-rwxr-xr-xaddons/email_template/email_template_account.py440
-rwxr-xr-xaddons/email_template/email_template_account_view.xml110
-rwxr-xr-xaddons/email_template/email_template_engines.py84
-rwxr-xr-xaddons/email_template/email_template_mailbox.py182
-rwxr-xr-xaddons/email_template/email_template_mailbox_view.xml170
-rwxr-xr-xaddons/email_template/email_template_scheduler_data.xml16
-rwxr-xr-xaddons/email_template/email_template_view.xml188
-rwxr-xr-xaddons/email_template/email_template_workflow.xml72
-rwxr-xr-xaddons/email_template/html2text.py455
-rwxr-xr-xaddons/email_template/security/email_template_security.xml19
-rwxr-xr-xaddons/email_template/wizard/__init__.py1
-rwxr-xr-xaddons/email_template/wizard/email_template_send_wizard.py235
-rwxr-xr-xaddons/email_template/wizard/email_template_send_wizard_view.xml64
-rw-r--r--addons/hr_recruitment/hr_recruitment_view.xml9
-rw-r--r--addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml1
-rw-r--r--addons/hr_timesheet_sheet/report/timesheet_report_view.xml8
-rw-r--r--addons/mail_gateway/mail_gateway_view.xml160
-rw-r--r--addons/marketing/marketing_view.xml10
-rw-r--r--addons/marketing/marketing_wizard.py12
-rwxr-xr-xaddons/marketing_campaign/__openerp__.py6
-rwxr-xr-xaddons/marketing_campaign/marketing_campaign.py36
-rw-r--r--addons/marketing_campaign/marketing_campaign_demo.xml271
-rw-r--r--addons/mrp/mrp_view.xml26
-rw-r--r--addons/mrp/report/mrp_production_order_view.xml86
-rw-r--r--addons/mrp_operations/mrp_operations_view.xml8
-rw-r--r--addons/mrp_procurement/mrp_procurement_view.xml24
-rw-r--r--addons/mrp_repair/mrp_repair_view.xml8
-rw-r--r--addons/point_of_sale/pos_view.xml14
-rw-r--r--addons/product/product_view.xml23
-rw-r--r--addons/profile_accounting/__openerp__.py2
-rw-r--r--addons/project/project_demo.xml10
-rw-r--r--addons/project/project_view.xml75
-rw-r--r--addons/project/report/project_report.py6
-rw-r--r--addons/project/report/project_report_view.xml51
-rw-r--r--addons/project_gtd/project_gtd.py6
-rw-r--r--addons/project_gtd/project_gtd_view.xml5
-rw-r--r--addons/project_issue/project_issue_view.xml45
-rw-r--r--addons/project_issue/report/project_issue_report_view.xml52
-rw-r--r--addons/project_long_term/project_long_term.py2
-rw-r--r--addons/project_long_term/project_long_term_view.xml20
-rw-r--r--addons/project_long_term/wizard/project_compute_tasks_view.xml14
-rw-r--r--addons/project_mrp/mrp.py5
-rw-r--r--addons/project_planning/project_planning_view.xml2
-rw-r--r--addons/project_timesheet/report/task_report_view.xml10
-rw-r--r--addons/purchase/purchase.py58
-rw-r--r--addons/purchase/purchase_view.xml45
-rw-r--r--addons/purchase/report/purchase_report_view.xml54
-rw-r--r--addons/purchase_requisition/purchase_requisition_view.xml26
-rw-r--r--addons/report_intrastat/report_intrastat_view.xml4
-rw-r--r--addons/resource/resource_view.xml20
-rw-r--r--addons/sale/report/sale_report.py51
-rw-r--r--addons/sale/report/sale_report_view.xml47
-rw-r--r--addons/sale/sale.py6
-rw-r--r--addons/sale/sale_view.xml45
-rw-r--r--addons/sale_crm/sale_crm_view.xml2
-rw-r--r--addons/sale_journal/report/sale_journal_report_view.xml74
-rw-r--r--addons/sale_journal/sale_journal_view.xml146
-rw-r--r--addons/scrum/scrum.py8
-rw-r--r--addons/scrum/scrum_view.xml55
-rw-r--r--addons/stock/stock.py20
-rw-r--r--addons/stock/stock_view.xml37
77 files changed, 3935 insertions, 764 deletions
diff --git a/addons/account/i18n/nl_BE.po b/addons/account/i18n/nl_BE.po
index f298c31854d..5df4bb0be72 100644
--- a/addons/account/i18n/nl_BE.po
+++ b/addons/account/i18n/nl_BE.po
@@ -7,30 +7,30 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-04-24 15:00+0000\n"
-"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
+"PO-Revision-Date: 2010-06-02 08:19+0000\n"
+"Last-Translator: jan@synkronized.be <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-04-17 04:08+0000\n"
+"X-Launchpad-Export-Date: 2010-06-03 03:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
#: field:account.tax.template,description:0
msgid "Internal Name"
-msgstr ""
+msgstr "Interne naam"
#. module: account
#: view:account.tax.code:0
msgid "Account Tax Code"
-msgstr ""
+msgstr "Belasting code"
#. module: account
#: model:ir.actions.act_window,name:account.action_invoice_tree9
#: model:ir.ui.menu,name:account.menu_action_invoice_tree9
msgid "Unpaid Supplier Invoices"
-msgstr ""
+msgstr "Onbetaalde inkoopfacturen"
#. module: account
#: model:ir.ui.menu,name:account.menu_finance_entries
@@ -50,12 +50,12 @@ msgstr ""
#. module: account
#: model:account.account.type,name:account.account_type_asset
msgid "Asset"
-msgstr ""
+msgstr "Activa"
#. module: account
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Ongeldige modelnaam in de actie-definitie."
#. module: account
#: help:account.journal,currency:0
@@ -65,7 +65,7 @@ msgstr ""
#. module: account
#: wizard_view:account_use_models,init_form:0
msgid "Select Message"
-msgstr ""
+msgstr "Kies bericht"
#. module: account
#: help:product.category,property_account_income_categ:0
@@ -82,19 +82,19 @@ msgstr ""
#. module: account
#: wizard_view:account.automatic.reconcile,reconcile:0
msgid "Reconciliation result"
-msgstr ""
+msgstr "Afletterresultaat"
#. module: account
#: model:ir.actions.act_window,name:account.act_account_acount_move_line_open_unreconciled
msgid "Unreconciled entries"
-msgstr ""
+msgstr "Niet afgeletterde boekingen"
#. module: account
#: field:account.invoice.tax,base_code_id:0
#: field:account.tax,base_code_id:0
#: field:account.tax.template,base_code_id:0
msgid "Base Code"
-msgstr ""
+msgstr "Basiscode"
#. module: account
#: view:account.account:0
@@ -2132,7 +2132,8 @@ msgid "Analytic Entry"
msgstr ""
#. module: account
-#: view:res.company:0 field:res.company,overdue_msg:0
+#: view:res.company:0
+#: field:res.company,overdue_msg:0
msgid "Overdue Payments Message"
msgstr ""
diff --git a/addons/account/report/account_balance.py b/addons/account/report/account_balance.py
index e4731e2c994..78683b5120b 100644
--- a/addons/account/report/account_balance.py
+++ b/addons/account/report/account_balance.py
@@ -22,9 +22,15 @@
import xml
import copy
from operator import itemgetter
-import time
import datetime
from report import report_sxw
+import xml.dom.minidom
+import os, time
+import osv
+import re
+import tools
+import pooler
+import sys
class account_balance(report_sxw.rml_parse):
_name = 'report.account.account.balance'
@@ -44,6 +50,10 @@ class account_balance(report_sxw.rml_parse):
})
self.context = context
+ def _add_header(self, node, header=1):
+ if header==0:
+ self.rml_header = ""
+ return True
def get_fiscalyear(self, form):
res=[]
if form.has_key('fiscalyear'):
@@ -56,16 +66,14 @@ class account_balance(report_sxw.rml_parse):
def get_periods(self, form):
result=''
- if form.has_key('periods') and form['periods'][0][2]:
- period_ids = form['periods'][0][2]
- self.cr.execute("select name from account_period where id =ANY(%s)" ,(period_ids))
- res = self.cr.fetchall()
- len_res = len(res)
- for r in res:
- if (r == res[len_res-1]):
- result+=r[0]+". "
+ if form.has_key('periods') and form['periods']:
+ period_ids = form['periods']
+ per_ids = self.pool.get('account.period').browse(self.cr,self.uid,form['periods'])
+ for r in per_ids:
+ if r == per_ids[len(per_ids)-1]:
+ result+=r.name+". "
else:
- result+=r[0]+", "
+ result+=r.name+", "
else:
fy_obj = self.pool.get('account.fiscalyear').browse(self.cr,self.uid,form['fiscalyear'])
res = fy_obj.period_ids
@@ -172,5 +180,8 @@ class account_balance(report_sxw.rml_parse):
def _sum_debit(self):
return self.sum_debit
-report_sxw.report_sxw('report.account.account.balance', 'account.account', 'addons/account/report/account_balance.rml', parser=account_balance, header=False)
+
+
+
+report_sxw.report_sxw('report.account.account.balance', 'account.account', 'addons/account/report/account_balance.rml', parser=account_balance, header=0)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_balance.rml b/addons/account/report/account_balance.rml
index fb8eb53c418..af4cee7a7ba 100644
--- a/addons/account/report/account_balance.rml
+++ b/addons/account/report/account_balance.rml
@@ -66,6 +66,27 @@
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
+ <blockTableStyle id="Table3a">
+ <blockAlignment value="LEFT"/>
+ <blockValign value="TOP"/>
+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
+ </blockTableStyle>
+
<blockTableStyle id="Table4">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
@@ -95,6 +116,8 @@
<paraStyle name="P9b" fontName="Helvetica" fontSize="9" leftIndent="0.0" alignment="LEFT"/>
<paraStyle name="P9b" fontName="Helvetica" fontSize="8" leftIndent="-5.0" alignment="LEFT"/>
<paraStyle name="P12" fontName="Helvetica-Bold" fontSize="8.0" leading="14" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
+ <paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
+ <paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P12a" fontName="Helvetica-Bold" fontSize="8.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P12b" fontName="Helvetica-Bold" fontSize="8.0" leading="14" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="P14" rightIndent="17.0" leftIndent="-0.0" fontName="Helvetica-Bold" fontSize="8.0" leading="10" spaceBefore="0.0" spaceAfter="6.0"/>
@@ -141,14 +164,46 @@
<para style="P2">
<font color="white"> </font>
</para>
-<blockTable colWidths="527.00" style="Table4" repeatRows="1">
+
+ <blockTable colWidths="78.0,108.0,108.0,108.0,138" style="Table3a">
+ <tr>
+ <td>
+ <para style="terp_tblheader_General_Centre">Fiscal Year</para>
+ </td>
+ <td>
+ <para style="terp_tblheader_General_Centre">End Date</para>
+ </td>
+ <td>
+ <para style="terp_tblheader_General_Centre">Start Date</para>
+ </td>
+ <td>
+ <para style="terp_tblheader_General_Centre">Display Account</para>
+ </td>
+ <td>
+ <para style="terp_tblheader_General_Centre">Periods</para>
+ </td>
+ </tr>
+ </blockTable>
+ <blockTable colWidths="78.0,108.0,108.0,108.0,138" style="Table3a">
<tr>
<td>
- <para style="P9a">[[ get_fiscalyear(data['form']) or removeParentNode('para') ]]:</para>
- <para style="P9b"><i> [[ get_periods(data['form']) or removeParentNode('para') ]]</i></para>
+ <para style="terp_default_Centre_8">[[ get_fiscalyear(data['form']) ]]</para>
+ </td>
+ <td>
+ <para style="terp_default_Centre_8">[[ data['form']['date_from'] ]]</para>
+ </td>
+ <td>
+ <para style="terp_default_Centre_8">[[ data['form']['date_to'] ]]</para>
+ </td>
+ <td>
+ <para style="terp_default_Centre_8">[[ (data['form']['display_account']=='bal_all' and 'All') or (data['form']['display_account']=='bal_mouvement' and 'With movements') or 'With balance is not equal to 0']]</para>
+ </td>
+ <td>
+ <para style="terp_default_Centre_8"> [[data['form']['periods'] and get_periods(data['form']) or '']]</para>
</td>
</tr>
-</blockTable>
+ </blockTable>
+
<para style="P2">
<font color="white"> </font>
diff --git a/addons/account_budget/crossovered_budget_view.xml b/addons/account_budget/crossovered_budget_view.xml
index 00dec853486..b48ccc55daa 100644
--- a/addons/account_budget/crossovered_budget_view.xml
+++ b/addons/account_budget/crossovered_budget_view.xml
@@ -178,12 +178,33 @@
</field>
</record>
+ <record id="view_crossovered_budget_search" model="ir.ui.view">
+ <field name="name">crossovered.budget.search</field>
+ <field name="model">crossovered.budget</field>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Budget">
+ <group col="20" colspan="4">
+ <filter string="Draft" domain="[('state','=','draft')]" help="Draft Budgets" default="1"/>
+ <filter string="To Validate" domain="[('state','=','validate')]" help="To Validate Budgets" />
+ <separator orientation="vertical"/>
+ <field name="name" select="1"/>
+ <field name="code" select="1" />
+ <field name="state"/>
+ <field name="date_from"/>
+ <field name="date_to"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
<record model="ir.actions.act_window" id="act_crossovered_budget_view">
<field name="name">Budget</field>
<field name="res_model">crossovered.budget</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="crossovered_budget_view_tree"/>
+ <field name="search_view_id" ref="view_crossovered_budget_search"/>
</record>
<menuitem parent="next_id_31"
id="menu_act_crossovered_budget_view"
diff --git a/addons/account_invoice_layout/account_invoice_layout.py b/addons/account_invoice_layout/account_invoice_layout.py
index 2317e0c65a9..fda547f3c68 100644
--- a/addons/account_invoice_layout/account_invoice_layout.py
+++ b/addons/account_invoice_layout/account_invoice_layout.py
@@ -170,6 +170,7 @@ class account_invoice_line(osv.osv):
_defaults = {
'state': lambda *a: 'article',
+ 'sequence': lambda *a : 0,
# 'account_id': _default_account
}
account_invoice_line()
diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml
index 2bd56a3b513..0882b6f0e1b 100644
--- a/addons/base_action_rule/base_action_rule_view.xml
+++ b/addons/base_action_rule/base_action_rule_view.xml
@@ -46,7 +46,7 @@
</group>
<separator colspan="4" string="Note"/>
<label align="0.0" colspan="4" width="900"
- string="The rule use a AND operator. The model must match all non empty fields so that the rule execute the action described in the 'Actions' tab." />
+ string="The rule uses the AND operator. The model must match all non-empty fields so that the rule executes the action described in the 'Actions' tab." />
</page>
<page string="Actions">
<separator colspan="4" string="Fields to Change"/>
diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml
index a5afddc9823..fc5140c8303 100644
--- a/addons/base_calendar/base_calendar_view.xml
+++ b/addons/base_calendar/base_calendar_view.xml
@@ -137,15 +137,14 @@
</record>
<!-- Calenadar's menu -->
-
- <menuitem id="base.menu_calendar_configuration" name="Calendar"
- parent="base.menu_base_config" sequence="10" />
+ <menuitem id="base.menu_calendar_configuration" name="Calendar"
+ parent="base.menu_config_address_book" sequence="15" />
<!-- Invitation menu -->
- <menuitem id="menu_attendee_invitations"
- name="Event Invitations" parent="base.menu_calendar_configuration"
- sequence="10" action="action_view_attendee_form" />
+ <menuitem id="menu_attendee_invitations"
+ name="Event Invitations" parent="base.menu_calendar_configuration"
+ sequence="10" action="action_view_attendee_form" />
<!-- ALARM FORM VIEW-->
@@ -192,11 +191,10 @@
<!-- Menu for Alarms-->
- <menuitem id="menu_crm_meeting_avail_alarm"
+ <menuitem id="menu_crm_meeting_avail_alarm"
groups="base.group_extended"
action="base_calendar.action_res_alarm_view"
parent="base.menu_calendar_configuration" />
-
<!-- Event Form View-->
<record model="ir.ui.view" id="event_form_view">
@@ -427,9 +425,9 @@
<!-- Event menu -->
- <menuitem id="menu_events"
- name="Events" parent="base.menu_calendar_configuration"
- sequence="5" action="action_view_event" />
+ <menuitem id="menu_events"
+ name="Events" parent="base.menu_calendar_configuration"
+ sequence="5" action="action_view_event" />
</data>
</openerp>
diff --git a/addons/base_vat/i18n/id.po b/addons/base_vat/i18n/id.po
index 8881f0627cc..e969ecfa9ad 100644
--- a/addons/base_vat/i18n/id.po
+++ b/addons/base_vat/i18n/id.po
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-11-09 13:47+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2010-06-03 01:30+0000\n"
+"Last-Translator: Abdul Munif Hanafi <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-04-17 04:03+0000\n"
+"X-Launchpad-Export-Date: 2010-06-03 03:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_vat
@@ -25,7 +25,7 @@ msgstr ""
#. module: base_vat
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "XML tidak sah untuk Menampilkan Arsitektur!"
#. module: base_vat
#: field:res.partner,vat_subjected:0
@@ -35,4 +35,4 @@ msgstr ""
#. module: base_vat
#: model:ir.module.module,shortdesc:base_vat.module_meta_information
msgid "VAT"
-msgstr ""
+msgstr "VAT"
diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py
index cc26ad89c89..657360a4206 100644
--- a/addons/crm/crm_phonecall.py
+++ b/addons/crm/crm_phonecall.py
@@ -90,6 +90,7 @@ class crm_phonecall(osv.osv, crm_case):
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'state': lambda *a: 'draft',
+ 'user_id': lambda self,cr,uid,ctx: uid,
'active': lambda *a: 1,
}
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 7b462646784..2b3f883024c 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -2,6 +2,10 @@
<openerp>
<data>
+ <menuitem id="menu_config_claim" name="Claim"
+ groups="base.group_extended"
+ parent="base.menu_base_config" sequence="8" />
+
<!-- Claims categories -->
<record id="crm_claim_categ_action" model="ir.actions.act_window">
@@ -13,8 +17,9 @@
<field name="context">{'object_id':'crm.claim'}</field>
</record>
- <menuitem action="crm_claim_categ_action"
- id="menu_crm_case_claim-act" parent="crm.menu_crm_case_categ" />
+ <menuitem action="crm_claim_categ_action" name="Categories"
+ id="menu_crm_case_claim-act" parent="menu_config_claim" />
+
<!-- Claim Stages -->
@@ -27,8 +32,8 @@
<field name="context">{'object_id':'crm.claim'}</field>
</record>
- <menuitem action="crm_claim_stage_act"
- id="menu_crm_claim_stage_act" parent="crm.menu_crm_case_stage" />
+ <menuitem action="crm_claim_stage_act" name="Stages"
+ id="menu_crm_claim_stage_act" parent="menu_config_claim" />
<!-- Claim Resource Type -->
@@ -41,9 +46,9 @@
<field name="context">{'object_id':'crm.claim'}</field>
</record>
- <menuitem action="crm_claim_resource_act"
+ <menuitem action="crm_claim_resource_act" name="Resource Type"
id="menu_crm_claim_stage_act"
- parent="crm.menu_crm_case_resource_type" />
+ parent="menu_config_claim" />
<!-- Claims -->
diff --git a/addons/crm_fundraising/crm_fundraising_view.xml b/addons/crm_fundraising/crm_fundraising_view.xml
index 78123fd32b7..6853da7c89a 100644
--- a/addons/crm_fundraising/crm_fundraising_view.xml
+++ b/addons/crm_fundraising/crm_fundraising_view.xml
@@ -1,6 +1,10 @@
<?xml version="1.0"?>
<openerp>
<data>
+ <!-- Fund Raising Configuration Menu -->
+ <menuitem id="menu_config_fundrising" name="Fund Raising"
+ groups="base.group_extended"
+ parent="base.menu_base_config" sequence="7" />
<!-- Fund Raising Categories Form View -->
@@ -13,9 +17,9 @@
<field name="context">{'object_id':'crm.fundraising'}</field>
</record>
- <menuitem action="crm_fund_categ_action"
+ <menuitem action="crm_fund_categ_action" name="Categories"
id="menu_crm_case_fundraising-act" groups="base.group_extended"
- parent="crm.menu_crm_case_categ" />
+ parent="menu_config_fundrising" />
<!-- Fund Stage Form View -->
@@ -28,10 +32,11 @@
<field name="context">{'object_id':'crm.fundraising'}</field>
</record>
- <menuitem action="crm_fundraising_stage_act"
- groups="base.group_extended"
+ <menuitem action="crm_fundraising_stage_act"
+ groups="base.group_extended" name="Stages"
id="menu_crm_fundraising_stage_act"
- parent="crm.menu_crm_case_stage" />
+ parent="menu_config_fundrising" />
+
<!-- Fund Resource Type Form View -->
@@ -44,10 +49,10 @@
<field name="context">{'object_id':'crm.fundraising'}</field>
</record>
- <menuitem action="crm_fundraising_resource_act"
- groups="base.group_extended"
+ <menuitem action="crm_fundraising_resource_act"
+ groups="base.group_extended" name="Resource Type"
id="menu_crm_fundraising_resource_act"
- parent="crm.menu_crm_case_resource_type" />
+ parent="menu_config_fundrising" />
<!-- Fund Raising Tree View -->
diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
index 4642f60e7e2..451f6c7119e 100644
--- a/addons/crm_helpdesk/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -1,6 +1,10 @@
<?xml version="1.0"?>
<openerp>
<data>
+ <!-- Helpdesk Support Categories Configuration Menu-->
+ <menuitem id="menu_config_helpdesk" name="Helpdesk"
+ groups="base.group_extended"
+ parent="base.menu_base_config" sequence="8" />
<!-- Helpdesk Support Categories Form View -->
@@ -13,8 +17,8 @@
<field name="context">{'object_id':'crm.helpdesk'}</field>
</record>
- <menuitem action="crm_helpdesk_categ_action"
- id="menu_crm_case_helpdesk-act" parent="crm.menu_crm_case_categ" />
+ <menuitem action="crm_helpdesk_categ_action" name="Categories"
+ id="menu_crm_case_helpdesk-act" parent="menu_config_helpdesk" />
<!-- Helpdesk Support Form View -->
diff --git a/addons/crm_profiling/crm_profiling_view.xml b/addons/crm_profiling/crm_profiling_view.xml
index 040dff1ff38..eeb95d77fc1 100644
--- a/addons/crm_profiling/crm_profiling_view.xml
+++ b/addons/crm_profiling/crm_profiling_view.xml
@@ -15,9 +15,9 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
- <menuitem parent="base.menu_crm_configuration" id="menu_segm_questionnaire"
- action="open_questionnaires" />
+ <menuitem parent="base.menu_crm_config_sales" id="menu_segm_questionnaire"
+ action="open_questionnaires" />
<record model="ir.actions.act_window" id="open_questions">
<field name="name">Questions</field>
@@ -25,7 +25,8 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
- <menuitem parent="base.menu_crm_configuration" id="menu_segm_answer"
+
+ <menuitem parent="base.menu_crm_config_sales" id="menu_segm_answer"
action="open_questions" />
<!-- Profiling Questionnaire Tree view -->
diff --git a/addons/email_template/__init__.py b/addons/email_template/__init__.py
new file mode 100755
index 00000000000..c959f7204da
--- /dev/null
+++ b/addons/email_template/__init__.py
@@ -0,0 +1,5 @@
+import email_template_account
+import email_template
+import email_template_mailbox
+import wizard
+
diff --git a/addons/email_template/__openerp__.py b/addons/email_template/__openerp__.py
new file mode 100755
index 00000000000..9c5f7bb5c70
--- /dev/null
+++ b/addons/email_template/__openerp__.py
@@ -0,0 +1,24 @@
+{
+ "name" : "Email Template for Open ERP",
+ "version" : "0.7 RC",
+ "author" : "Open ERP",
+ "website" : "http://openerp.com",
+ "category" : "Added functionality",
+ "depends" : ['base'],
+ "description": """
+ Email Template is extraction of Power Email basically just to send the emails.
+ """,
+ "init_xml": ['email_template_scheduler_data.xml'],
+ "update_xml": [
+ 'security/email_template_security.xml',
+ 'email_template_workflow.xml',
+ 'email_template_account_view.xml',
+ 'email_template_view.xml',
+ 'email_template_mailbox_view.xml',
+ 'wizard/email_template_send_wizard_view.xml',
+ ],
+ "installable": True,
+ "active": False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
new file mode 100755
index 00000000000..6c46da458c6
--- /dev/null
+++ b/addons/email_template/email_template.py
@@ -0,0 +1,698 @@
+import base64
+import random
+import time
+import types
+import netsvc
+
+LOGGER = netsvc.Logger()
+
+TEMPLATE_ENGINES = []
+
+from osv import osv, fields
+from tools.translate import _
+from mako.template import Template #For backward combatibility
+try:
+ from mako.template import Template as MakoTemplate
+ from mako import exceptions
+ TEMPLATE_ENGINES.append(('mako', 'Mako Templates'))
+except:
+ LOGGER.notifyChannel(
+ _("Email Template"),
+ netsvc.LOG_ERROR,
+ _("Mako templates not installed")
+ )
+try:
+ from django.template import Context, Template as DjangoTemplate
+ #Workaround for bug:
+ #http://code.google.com/p/django-tagging/issues/detail?id=110
+ from django.conf import settings
+ settings.configure()
+ #Workaround ends
+ TEMPLATE_ENGINES.append(('django', 'Django Template'))
+except:
+ LOGGER.notifyChannel(
+ _("Email Template"),
+ netsvc.LOG_ERROR,
+ _("Django templates not installed")
+ )
+
+import email_template_engines
+import tools
+import report
+import pooler
+
+
+def get_value(cursor, user, recid, message=None, template=None, context=None):
+ """
+ Evaluates an expression and returns its value
+ @param cursor: Database Cursor
+ @param user: ID of current user
+ @param recid: ID of the target record under evaluation
+ @param message: The expression to be evaluated
+ @param template: BrowseRecord object of the current template
+ @param context: Open ERP Context
+ @return: Computed message (unicode) or u""
+ """
+ pool = pooler.get_pool(cursor.dbname)
+ if message is None:
+ message = {}
+ #Returns the computed expression
+ if message:
+ try:
+ message = tools.ustr(message)
+ object = pool.get(template.model_int_name).browse(cursor, user, recid, context)
+ env = {
+ 'user':pool.get('res.users').browse(cursor, user, user, context),
+ 'db':cursor.dbname
+ }
+ if template.template_language == 'mako':
+ templ = MakoTemplate(message, input_encoding='utf-8')
+ reply = MakoTemplate(message).render_unicode(object=object,
+ peobject=object,
+ env=env,
+ format_exceptions=True)
+ elif template.template_language == 'django':
+ templ = DjangoTemplate(message)
+ env['object'] = object
+ env['peobject'] = object
+ reply = templ.render(Context(env))
+ return reply or False
+ except Exception:
+ return u""
+ else:
+ return message
+
+class email_template(osv.osv):
+ "Templates for sending Email"
+
+ _name = "email.template"
+ _description = 'Email Templates for Models'
+
+ def change_model(self, cursor, user, ids, object_name, context=None):
+ if object_name:
+ mod_name = self.pool.get('ir.model').read(
+ cursor,
+ user,
+ object_name,
+ ['model'], context)['model']
+ else:
+ mod_name = False
+ return {
+ 'value':{'model_int_name':mod_name}
+ }
+
+ _columns = {
+ 'name' : fields.char('Name of Template', size=100, required=True),
+ 'object_name':fields.many2one('ir.model', 'Model'),
+ 'model_int_name':fields.char('Model Internal Name', size=200,),
+ 'def_to':fields.char(
+ 'Recepient (To)',
+ size=250,
+ help="The default recepient of email."
+ "Placeholders can be used here."),
+ 'def_cc':fields.char(
+ 'Default CC',
+ size=250,
+ help="The default CC for the email."
+ " Placeholders can be used here."),
+ 'def_bcc':fields.char(
+ 'Default BCC',
+ size=250,
+ help="The default BCC for the email."
+ " Placeholders can be used here."),
+ 'lang':fields.char(
+ 'Language',
+ size=250,
+ help="The default language for the email."
+ " Placeholders can be used here. "
+ "eg. ${object.partner_id.lang}"),
+ 'def_subject':fields.char(
+ 'Default Subject',
+ size=200,
+ help="The default subject of email."
+ " Placeholders can be used here.",
+ translate=True),
+ 'def_body_text':fields.text(
+ 'Standard Body (Text)',
+ help="The text version of the mail",
+ translate=True),
+ 'def_body_html':fields.text(
+ 'Body (Text-Web Client Only)',
+ help="The text version of the mail",
+ translate=True),
+ 'use_sign':fields.boolean(
+ 'Use Signature',
+ help="the signature from the User details"
+ "will be appened to the mail"),
+ 'file_name':fields.char(
+ 'File Name Pattern',
+ size=200,
+ help="File name pattern can be specified with placeholders."
+ "eg. 2009_SO003.pdf",
+ translate=True),
+ 'report_template':fields.many2one(
+ 'ir.actions.report.xml',
+ 'Report to send'),
+ 'ref_ir_act_window':fields.many2one(
+ 'ir.actions.act_window',
+ 'Window Action',
+ readonly=True),
+ 'ref_ir_value':fields.many2one(
+ 'ir.values',
+ 'Wizard Button',
+ readonly=True),
+ 'allowed_groups':fields.many2many(
+ 'res.groups',
+ 'template_group_rel',
+ 'templ_id', 'group_id',
+ string="Allowed User Groups",
+ help="Only users from these groups will be"
+ " allowed to send mails from this Template"),
+ 'enforce_from_account':fields.many2one(
+ 'email_template.account',
+ string="Enforce From Account",
+ help="Emails will be sent only from this account.",
+ domain="[('company','=','yes')]"),
+ 'model_object_field':fields.many2one(
+ 'ir.model.fields',
+ string="Field",
+ help="Select the field from the model you want to use."
+ "\nIf it is a relationship field you will be able to "
+ "choose the nested values in the box below\n(Note:If "
+ "there are no values make sure you have selected the"
+ " correct model)",
+ store=False),
+ 'sub_object':fields.many2one(
+ 'ir.model',
+ 'Sub-model',
+ help='When a relation field is used this field'
+ ' will show you the type of field you have selected',
+ store=False),
+ 'sub_model_object_field':fields.many2one(
+ 'ir.model.fields',
+ 'Sub Field',
+ help="When you choose relationship fields "
+ "this field will specify the sub value you can use.",
+ store=False),
+ 'null_value':fields.char(
+ 'Null Value',
+ help="This Value is used if the field is empty",
+ size=50, store=False),
+ 'copyvalue':fields.char(
+ 'Expression',
+ size=100,
+ help="Copy and paste the value in the "
+ "location you want to use a system value.",
+ store=False),
+ 'table_html':fields.text(
+ 'HTML code',
+ help="Copy this html code to your HTML message"
+ " body for displaying the info in your mail.",
+ store=False),
+ #Template language(engine eg.Mako) specifics
+ 'template_language':fields.selection(
+ TEMPLATE_ENGINES,
+ 'Templating Language',
+ required=True
+ )
+ }
+
+ _defaults = {
+
+ }
+ _sql_constraints = [
+ ('name', 'unique (name)', _('The template name must be unique !'))
+ ]
+
+ def create(self, cr, uid, vals, context=None):
+ id = super(email_template, self).create(cr, uid, vals, context)
+ src_obj = self.pool.get('ir.model').read(cr, uid, vals['object_name'], ['model'], context)['model']
+ vals['ref_ir_act_window'] = self.pool.get('ir.actions.act_window').create(cr, uid, {
+ 'name': _("%s Mail Form") % vals['name'],
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'email_template.send.wizard',
+ 'src_model': src_obj,
+ 'view_type': 'form',
+ 'context': "{'src_model':'%s','template_id':'%d','src_rec_id':active_id,'src_rec_ids':active_ids}" % (src_obj, id),
+ 'view_mode':'form,tree',
+ 'view_id': self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'email_template.send.wizard.form')], context=context)[0],
+ 'target': 'new',
+ 'auto_refresh':1
+ }, context)
+ vals['ref_ir_value'] = self.pool.get('ir.values').create(cr, uid, {
+ 'name': _('Send Mail (%s)') % vals['name'],
+ 'model': src_obj,
+ 'key2': 'client_action_multi',
+ 'value': "ir.actions.act_window," + str(vals['ref_ir_act_window']),
+ 'object': True,
+ }, context)
+ self.write(cr, uid, id, {
+ 'ref_ir_act_window': vals['ref_ir_act_window'],
+ 'ref_ir_value': vals['ref_ir_value'],
+ }, context)
+ return id
+
+ def unlink(self, cr, uid, ids, context=None):
+ for template in self.browse(cr, uid, ids, context):
+ obj = self.pool.get(template.object_name.model)
+ try:
+ if template.ref_ir_act_window:
+ self.pool.get('ir.actions.act_window').unlink(cr, uid, template.ref_ir_act_window.id, context)
+ if template.ref_ir_value:
+ self.pool.get('ir.values').unlink(cr, uid, template.ref_ir_value.id, context)
+ except:
+ raise osv.except_osv(_("Warning"), _("Deletion of Record failed"))
+ return super(email_template, self).unlink(cr, uid, ids, context)
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ if default is None:
+ default = {}
+ default = default.copy()
+ old = self.read(cr, uid, id, ['name'], context=context)
+ new_name = _("Copy of template ") + old.get('name', 'No Name')
+ check = self.search(cr, uid, [('name', '=', new_name)], context=context)
+ if check:
+ new_name = new_name + '_' + random.choice('abcdefghij') + random.choice('lmnopqrs') + random.choice('tuvwzyz')
+ default.update({'name':new_name})
+ return super(email_template, self).copy(cr, uid, id, default, context)
+
+ def compute_pl(self,
+ model_object_field,
+ sub_model_object_field,
+ null_value, template_language='mako'):
+ """
+ Returns the expression based on data provided
+ @param model_object_field: First level field
+ @param sub_model_object_field: Second level drilled down field (M2O)
+ @param null_value: What has to be returned if the value is empty
+ @param template_language: The language used for templating
+ @return: computed expression
+ """
+ #Configure for MAKO
+ copy_val = ''
+ if template_language == 'mako':
+ if model_object_field:
+ copy_val = "${object." + model_object_field
+ if sub_model_object_field:
+ copy_val += "." + sub_model_object_field
+ if null_value:
+ copy_val += " or '" + null_value + "'"
+ if model_object_field:
+ copy_val += "}"
+ elif template_language == 'django':
+ if model_object_field:
+ copy_val = "{{object." + model_object_field
+ if sub_model_object_field:
+ copy_val += "." + sub_model_object_field
+ if null_value:
+ copy_val = copy_val + '|default:"' + null_value + '"'
+ copy_val = copy_val + "}}"
+ return copy_val
+
+ def onchange_model_object_field(self, cr, uid, ids, model_object_field, template_language, context=None):
+ if not model_object_field:
+ return {}
+ result = {}
+ field_obj = self.pool.get('ir.model.fields').browse(cr, uid, model_object_field, context)
+ #Check if field is relational
+ if field_obj.ttype in ['many2one', 'one2many', 'many2many']:
+ res_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', field_obj.relation)], context=context)
+ if res_ids:
+ result['sub_object'] = res_ids[0]
+ result['copyvalue'] = self.compute_pl(False,
+ False,
+ False,
+ template_language)
+ result['sub_model_object_field'] = False
+ result['null_value'] = False
+ else:
+ #Its a simple field... just compute placeholder
+ result['sub_object'] = False
+ result['copyvalue'] = self.compute_pl(field_obj.name,
+ False,
+ False,
+ template_language
+ )
+ result['sub_model_object_field'] = False
+ result['null_value'] = False
+ return {'value':result}
+
+ def onchange_sub_model_object_field(self, cr, uid, ids, model_object_field, sub_model_object_field, template_language, context=None):
+ if not model_object_field or not sub_model_object_field:
+ return {}
+ result = {}
+ field_obj = self.pool.get('ir.model.fields').browse(cr, uid, model_object_field, context)
+ if field_obj.ttype in ['many2one', 'one2many', 'many2many']:
+ res_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', field_obj.relation)], context=context)
+ sub_field_obj = self.pool.get('ir.model.fields').browse(cr, uid, sub_model_object_field, context)
+ if res_ids:
+ result['sub_object'] = res_ids[0]
+ result['copyvalue'] = self.compute_pl(field_obj.name,
+ sub_field_obj.name,
+ False,
+ template_language
+ )
+ result['sub_model_object_field'] = sub_model_object_field
+ result['null_value'] = False
+ else:
+ #Its a simple field... just compute placeholder
+ result['sub_object'] = False
+ result['copyvalue'] = self.compute_pl(field_obj.name,
+ False,
+ False,
+ template_language
+ )
+ result['sub_model_object_field'] = False
+ result['null_value'] = False
+ return {'value':result}
+
+ def onchange_null_value(self, cr, uid, ids, model_object_field, sub_model_object_field, null_value, template_language, context=None):
+ if not model_object_field and not null_value:
+ return {}
+ result = {}
+ field_obj = self.pool.get('ir.model.fields').browse(cr, uid, model_object_field, context)
+ if field_obj.ttype in ['many2one', 'one2many', 'many2many']:
+ res_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', field_obj.relation)], context=context)
+ sub_field_obj = self.pool.get('ir.model.fields').browse(cr, uid, sub_model_object_field, context)
+ if res_ids:
+ result['sub_object'] = res_ids[0]
+ result['copyvalue'] = self.compute_pl(field_obj.name,
+ sub_field_obj.name,
+ null_value,
+ template_language
+ )
+ result['sub_model_object_field'] = sub_model_object_field
+ result['null_value'] = null_value
+ else:
+ #Its a simple field... just compute placeholder
+ result['sub_object'] = False
+ result['copyvalue'] = self.compute_pl(field_obj.name,
+ False,
+ null_value,
+ template_language
+ )
+ result['sub_model_object_field'] = False
+ result['null_value'] = null_value
+ return {'value':result}
+
+ def generate_attach_reports(self,
+ cursor,
+ user,
+ template,
+ record_id,
+ mail,
+ context=None):
+ """
+ Generate report to be attached and attach it
+ to the email
+
+ @param cursor: Database Cursor
+ @param user: ID of User
+ @param template: Browse record of
+ template
+ @param record_id: ID of the target model
+ for which this mail has
+ to be generated
+ @param mail: Browse record of email object
+ @return: True
+ """
+ reportname = 'report.' + \
+ self.pool.get('ir.actions.report.xml').read(
+ cursor,
+ user,
+ template.report_template.id,
+ ['report_name'],
+ context)['report_name']
+ service = netsvc.LocalService(reportname)
+ data = {}
+ data['model'] = template.model_int_name
+ (result, format) = service.create(cursor,
+ user,
+ [record_id],
+ data,
+ context)
+ attachment_obj = self.pool.get('ir.attachment')
+ new_att_vals = {
+ 'name':mail.subject + ' (Email Attachment)',
+ 'datas':base64.b64encode(result),
+ 'datas_fname':tools.ustr(
+ get_value(
+ cursor,
+ user,
+ record_id,
+ template.file_name,
+ template,
+ context
+ ) or 'Report') + "." + format,
+ 'description':mail.subject or "No Description",
+ 'res_model':'email_template.mailbox',
+ 'res_id':mail.id
+ }
+ attachment_id = attachment_obj.create(cursor,
+ user,
+ new_att_vals,
+ context)
+ if attachment_id:
+ self.pool.get('email_template.mailbox').write(
+ cursor,
+ user,
+ mail.id,
+ {
+ 'attachments_ids':[
+ [6, 0, [attachment_id]]
+ ],
+ 'mail_type':'multipart/mixed'
+ },
+ context)
+ return True
+
+ def generate_mailbox_item_from_template(self,
+ cursor,
+ user,
+ template,
+ record_id,
+ context=None):
+ """
+ Generates an email from the template for
+ record record_id of target object
+
+ @param cursor: Database Cursor
+ @param user: ID of User
+ @param template: Browse record of
+ template
+ @param record_id: ID of the target model
+ for which this mail has
+ to be generated
+ @return: ID of created object
+ """
+ if context is None:
+ context = {}
+ #If account to send from is in context select it, else use enforced account
+ if 'account_id' in context.keys():
+ from_account = self.pool.get('email_template.account').read(
+ cursor,
+ user,
+ context.get('account_id'),
+ ['name', 'email_id'],
+ context
+ )
+ else:
+ from_account = {
+ 'id':template.enforce_from_account.id,
+ 'name':template.enforce_from_account.name,
+ 'email_id':template.enforce_from_account.email_id
+ }
+ lang = get_value(cursor,
+ user,
+ record_id,
+ template.lang,
+ template,
+ context)
+ if lang:
+ ctx = context.copy()
+ ctx.update({'lang':lang})
+ template = self.browse(cursor, user, template_id, context=ctx)
+ mailbox_values = {
+ 'email_from': tools.ustr(from_account['name']) + \
+ "<" + tools.ustr(from_account['email_id']) + ">",
+ 'email_to':get_value(cursor,
+ user,
+ record_id,
+ template.def_to,
+ template,
+ context),
+ 'email_cc':get_value(cursor,
+ user,
+ record_id,
+ template.def_cc,
+ template,
+ context),
+ 'email_bcc':get_value(cursor,
+ user,
+ record_id,
+ template.def_bcc,
+ template,
+ context),
+ 'subject':get_value(cursor,
+ user,
+ record_id,
+ template.def_subject,
+ template,
+ context),
+ 'body_text':get_value(cursor,
+ user,
+ record_id,
+ template.def_body_text,
+ template,
+ context),
+ 'body_html':get_value(cursor,
+ user,
+ record_id,
+ template.def_body_html,
+ template,
+ context),
+ 'account_id' :from_account['id'],
+ #This is a mandatory field when automatic emails are sent
+ 'state':'na',
+ 'folder':'drafts',
+ 'mail_type':'multipart/alternative'
+ }
+ #Use signatures if allowed
+ if template.use_sign:
+ sign = self.pool.get('res.users').read(cursor,
+ user,
+ user,
+ ['signature'],
+ context)['signature']
+ if mailbox_values['body_text']:
+ mailbox_values['body_text'] += sign
+ if mailbox_values['body_html']:
+ mailbox_values['body_html'] += sign
+ mailbox_id = self.pool.get('email_template.mailbox').create(
+ cursor,
+ user,
+ mailbox_values,
+ context)
+ return mailbox_id
+
+ def generate_mail(self,
+ cursor,
+ user,
+ template_id,
+ record_ids,
+ context=None):
+ if context is None:
+ context = {}
+ template = self.browse(cursor, user, template_id, context=context)
+ if not template:
+ raise Exception("The requested template could not be loaded")
+ for record_id in record_ids:
+ mailbox_id = self._generate_mailbox_item_from_template(
+ cursor,
+ user,
+ template,
+ record_id,
+ context)
+ mail = self.pool.get('email_template.mailbox').browse(
+ cursor,
+ user,
+ mailbox_id,
+ context=context
+ )
+ if template.report_template:
+ self._generate_attach_reports(
+ cursor,
+ user,
+ template,
+ record_id,
+ mail,
+ context
+ )
+ self.pool.get('email_template.mailbox').write(
+ cursor,
+ user,
+ mailbox_id,
+ {'folder':'outbox'},
+ context=context
+ )
+ return True
+
+email_template()
+
+class email_template_preview(osv.osv_memory):
+ _name = "email_template.preview"
+ _description = "Email Template Preview"
+
+ def _get_model_recs(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ #Fills up the selection box which allows records from the selected object to be displayed
+ self.context = context
+ if 'active_id' in context.keys():
+# context['active_id'] = 5
+ ref_obj_id = self.pool.get('email.template').read(cr, uid, context['active_id'], ['object_name'], context)
+ ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id[0], ['model'], context)['model']
+ ref_obj_ids = self.pool.get(ref_obj_name).search(cr, uid, [], context=context)
+ ref_obj_recs = self.pool.get(ref_obj_name).name_get(cr, uid, ref_obj_ids, context)
+ return ref_obj_recs
+
+ def _default_model(self, cursor, user, context=None):
+ """
+ Returns the default value for model field
+ @param cursor: Database Cursor
+ @param user: ID of current user
+ @param context: Open ERP Context
+ """
+ return self.pool.get('email.template').read(
+ cursor,
+ user,
+ context['active_id'],
+ ['object_name'],
+ context)['object_name']
+
+ _columns = {
+ 'ref_template':fields.many2one(
+ 'email.template',
+ 'Template', readonly=True),
+ 'rel_model':fields.many2one('ir.model', 'Model', readonly=True),
+ 'rel_model_ref':fields.selection(_get_model_recs, 'Referred Document'),
+ 'to':fields.char('To', size=250, readonly=True),
+ 'cc':fields.char('CC', size=250, readonly=True),
+ 'bcc':fields.char('BCC', size=250, readonly=True),
+ 'subject':fields.char('Subject', size=200, readonly=True),
+ 'body_text':fields.text('Body', readonly=True),
+ 'body_html':fields.text('Body', readonly=True),
+ 'report':fields.char('Report Name', size=100, readonly=True),
+ }
+ _defaults = {
+ 'ref_template': lambda self, cr, uid, ctx:ctx['active_id'],
+ 'rel_model': _default_model
+ }
+
+ def on_change_ref(self, cr, uid, ids, rel_model_ref, context=None):
+ if context is None:
+ context = {}
+ if not rel_model_ref:
+ return {}
+ vals = {}
+ if context == {}:
+ context = self.context
+ template = self.pool.get('email.template').browse(cr, uid, context['active_id'], context)
+ #Search translated template
+ lang = get_value(cr, uid, rel_model_ref, template.lang, template, context)
+ if lang:
+ ctx = context.copy()
+ ctx.update({'lang':lang})
+ template = self.pool.get('email.template').browse(cr, uid, context['active_id'], ctx)
+ vals['to'] = get_value(cr, uid, rel_model_ref, template.def_to, template, context)
+ vals['cc'] = get_value(cr, uid, rel_model_ref, template.def_cc, template, context)
+ vals['bcc'] = get_value(cr, uid, rel_model_ref, template.def_bcc, template, context)
+ vals['subject'] = get_value(cr, uid, rel_model_ref, template.def_subject, template, context)
+ vals['body_text'] = get_value(cr, uid, rel_model_ref, template.def_body_text, template, context)
+ vals['body_html'] = get_value(cr, uid, rel_model_ref, template.def_body_html, template, context)
+ vals['report'] = get_value(cr, uid, rel_model_ref, template.file_name, template, context)
+ return {'value':vals}
+
+email_template_preview()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/email_template_account.py b/addons/email_template/email_template_account.py
new file mode 100755
index 00000000000..2503d19cd10
--- /dev/null
+++ b/addons/email_template/email_template_account.py
@@ -0,0 +1,440 @@
+from osv import osv, fields
+from html2text import html2text
+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 re
+import netsvc
+import string
+import email
+import time, datetime
+import email_template_engines
+from tools.translate import _
+import tools
+
+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('Email Account Desc',
+ size=64, required=True,
+ readonly=True, select=True,
+ states={'draft':[('readonly', False)]}),
+ 'user':fields.many2one('res.users',
+ 'Related User', required=True,
+ readonly=True, states={'draft':[('readonly', False)]}),
+ 'email_id': fields.char('Email ID',
+ size=120, required=True,
+ readonly=True, states={'draft':[('readonly', False)]} ,
+ help=" eg:yourname@yourdomain.com "),
+ 'smtpserver': fields.char('Server',
+ size=120, required=True,
+ readonly=True, states={'draft':[('readonly', False)]},
+ help="Enter name of outgoing server,eg:smtp.gmail.com "),
+ 'smtpport': fields.integer('SMTP Port ',
+ size=64, required=True,
+ readonly=True, states={'draft':[('readonly', False)]},
+ help="Enter port number,eg:SMTP-587 "),
+ 'smtpuname': fields.char('User Name',
+ size=120, required=False,
+ readonly=True, states={'draft':[('readonly', False)]}),
+ 'smtppass': fields.char('Password',
+ size=120, invisible=True,
+ required=False, readonly=True,
+ states={'draft':[('readonly', False)]}),
+ 'smtptls':fields.boolean('Use TLS',
+ states={'draft':[('readonly', False)]}, readonly=True),
+
+ 'smtpssl':fields.boolean('Use 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'),
+ ('both', 'Both HTML & Text')
+ ], 'Mail Format', required=True),
+ 'allowed_groups':fields.many2many(
+ 'res.groups',
+ 'account_group_rel', 'templ_id', 'group_id',
+ string="Allowed User Groups",
+ help="Only users from these groups will be" \
+ "allowed to send mails from this ID"),
+ 'company':fields.selection([
+ ('yes', 'Yes'),
+ ('no', 'No')
+ ], 'Company Mail A/c',
+ readonly=True,
+ help="Select if this mail account does not belong" \
+ "to specific user but the organisation as a whole." \
+ "eg:info@somedomain.com",
+ required=True, states={
+ 'draft':[('readonly', False)]
+ }),
+
+ 'state':fields.selection([
+ ('draft', 'Initiated'),
+ ('suspended', 'Suspended'),
+ ('approved', 'Approved')
+ ],
+ 'Account Status', required=True, readonly=True),
+ }
+
+ _defaults = {
+ 'name':lambda self, cursor, user, context:self.pool.get(
+ 'res.users'
+ ).read(
+ cursor,
+ user,
+ user,
+ ['name'],
+ context
+ )['name'],
+ 'smtpssl':lambda * a:True,
+ 'state':lambda * a:'draft',
+ '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 _constraint_unique(self, cursor, user, ids):
+ """
+ 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 on_change_emailid(self, cursor, user, ids, name=None, email_id=None, context=None):
+ """
+ Called when the email ID field changes.
+
+ UI enhancement
+ Writes the same email value to the smtpusername
+ and incoming username
+ """
+ #TODO: Check and remove the write. Is it needed?
+ self.write(cursor, user, ids, {'state':'draft'}, context=context)
+ return {
+ 'value': {
+ 'state': 'draft',
+ 'smtpuname':email_id,
+ 'isuser':email_id
+ }
+ }
+
+ 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)
+ 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(this_object.smtpuname, 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") % error
+ )
+
+ def do_approval(self, cr, uid, ids, context={}):
+ #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)
+ 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, 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 split_to_ids(self, ids_as_str):
+ """
+ Identifies email IDs separated by separators
+ and returns a list
+ TODO: Doc this
+ "a@b.com,c@bcom; d@b.com;e@b.com->['a@b.com',...]"
+ """
+ email_sep_by_commas = ids_as_str \
+ .replace('; ', ',') \
+ .replace(';', ',') \
+ .replace(', ', ',')
+ return email_sep_by_commas.split(',')
+
+ def get_ids_from_dict(self, addresses={}):
+ """
+ TODO: Doc this
+ """
+ result = {'all':[]}
+ keys = ['To', 'CC', 'BCC']
+ for each in keys:
+ ids_as_list = self.split_to_ids(addresses.get(each, u''))
+ while u'' in ids_as_list:
+ ids_as_list.remove(u'')
+ result[each] = ids_as_list
+ result['all'].extend(ids_as_list)
+ return result
+
+ def send_mail(self, cr, uid, ids, addresses, subject='', body=None, payload=None, context=None):
+ #TODO: Replace all this crap 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:
+ msg = MIMEMultipart()
+ if subject:
+ msg['Subject'] = subject
+ sender_name = Header(core_obj.name, 'utf-8').encode()
+ msg['From'] = sender_name + " <" + core_obj.email_id + ">"
+ msg['Organization'] = tools.ustr(core_obj.user.company_id.name)
+ msg['Date'] = formatdate()
+ addresses_l = self.get_ids_from_dict(addresses)
+ if addresses_l['To']:
+ msg['To'] = u','.join(addresses_l['To'])
+ if addresses_l['CC']:
+ msg['CC'] = u','.join(addresses_l['CC'])
+# if addresses_l['BCC']:
+# msg['BCC'] = u','.join(addresses_l['BCC'])
+ 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 == 'text' or core_obj.send_pref == 'both':
+ body_text = body.get('text', u'No Mail Message')
+ body_text = tools.ustr(body_text)
+ msg.attach(MIMEText(body_text.encode("utf-8"), _charset='UTF-8'))
+ if core_obj.send_pref == 'html' or core_obj.send_pref == 'both':
+ html_body = body.get('html', u'')
+ if len(html_body) == 0 or html_body == u'':
+ html_body = body.get('text', u'<p>No Mail Message</p>').replace('\n', '<br/>').replace('\r', '<br/>')
+ html_body = tools.ustr(html_body)
+ msg.attach(MIMEText(html_body.encode("utf-8"), _subtype='html', _charset='UTF-8'))
+ #Now add attachments if any
+ for file in payload.keys():
+ 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)
+ msg.attach(part)
+ except Exception, error:
+ logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:MIME Error\nDescription: %s") % (id, error))
+ return error
+ try:
+ #print msg['From'],toadds
+ serv.sendmail(msg['From'], addresses_l['all'], msg.as_string())
+ except Exception, error:
+ logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Server Send Error\nDescription: %s") % (id, error))
+ return 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)
+
+ 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
+ #print time_as_string
+ 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')
+ #print date_as_date
+ except Exception, e:
+ logger.notifyChannel(
+ _("Email Template"),
+ netsvc.LOG_WARNING,
+ _(
+ "Datetime Extraction failed.Date:%s \
+ \tError:%s") % (
+ time_as_string,
+ e)
+ )
+ return date_as_date
+
+ def send_receive(self, cr, uid, ids, context=None):
+ self.get_mails(cr, uid, ids, context)
+ 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:
diff --git a/addons/email_template/email_template_account_view.xml b/addons/email_template/email_template_account_view.xml
new file mode 100755
index 00000000000..5f11fa033f4
--- /dev/null
+++ b/addons/email_template/email_template_account_view.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <menuitem name="Tools" id="base.menu_tools" icon="STOCK_PREFERENCES" sequence="15"/>
+ <menuitem name="Email Template" id="menu_email_template" parent="base.menu_tools"/>
+
+ <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">
+ <field name="smtpserver" select="1" colspan="2" />
+ <field name="smtpport" select="2" colspan="2" />
+ <field name="smtpssl" select="2" colspan="2" />
+ <field name="smtptls" select="2" colspan="2" />
+ </group>
+ <button name="check_outgoing_connection" type="object" string="Check Outgoing Connection" />
+ <separator string="User Information" colspan="4" />
+ <group col="2" colspan="2">
+ <field name="email_id" select="1" on_change="on_change_emailid(name,email_id)" 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>
+ <page string="security" attrs="{'invisible':[('company','!=','yes')]}">
+ <field name="allowed_groups" attrs="{'required':[('company','=','yes')]}" nolabel="1"/>
+ </page>
+ </notebook>
+ <group colspan="4" col="10">
+ <field name="state" select="1"/>
+ <button string="Approve Account" name="button_approval" states="draft" type="workflow"/>
+ <button string="Suspend Account" name="button_suspended" states="approved" type="workflow" />
+ <button string="Request Re-activation" name="get_reapprove" states="suspended" type="workflow" />
+ <button string="Send/Receive" name="send_receive" states="approved" type="object" />
+ </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 string="SMTP Server">
+ <field name="name" select="2" />
+ <field name="email_id" select="2" />
+ <field name="smtpuname" select="2" />
+ <field name="user" select="2" />
+ <field name="smtpserver" select="2" />
+ <field name="smtpport" select="2" />
+ <field name="state" select="2" />
+ </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="Accounts">
+ <filter icon="terp-crm" string="My Accounts" name="my" domain="[('user','=',uid)]"/>
+ <filter icon="terp-crm" string="Personal Accounts" domain="[('company','=','no')]"/>
+ <filter icon="terp-crm" string="Company Accounts" domain="[('company','=','yes')]"/>
+ <separator orientation="vertical"/>
+ <filter icon="terp-crm" string="Draft" name="draft" domain="[('state','=','draft')]"/>
+ <filter icon="terp-crm" string="Suspended" domain="[('state','=','suspended')]"/>
+ <separator orientation="vertical"/>
+ <field name="name" select="1"/>
+ <field name="user" 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">{'group_by': [], 'search_default_draft': 1, 'search_default_my': 1}</field>
+ <field name="search_view_id" ref="view_email_template_account_search"/>
+ </record>
+
+ <menuitem name="Configuration" id="menu_email_template_configuration" parent="menu_email_template" />
+
+ <menuitem name="All Accounts" id="menu_email_template_account_all" parent="menu_email_template_configuration" action="action_email_template_account_tree_all" groups="res_groups_email_template_manager" />
+
+ </data>
+</openerp>
+
+
+
+
diff --git a/addons/email_template/email_template_engines.py b/addons/email_template/email_template_engines.py
new file mode 100755
index 00000000000..2fc58310e9b
--- /dev/null
+++ b/addons/email_template/email_template_engines.py
@@ -0,0 +1,84 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+from osv import fields,osv
+import pooler
+import netsvc
+import re
+
+class email_template_engines(osv.osv):
+ _name = "email_template.engines"
+ _description = "Email Template Engine"
+
+# def __init__(self):
+# print "Started Engine"
+
+ def check(self):
+ print "Start self check"
+
+ def strip_html(self,text):
+ #Removes HTML, Have to check if still relevent
+ if text:
+ def fixup(m):
+ text = m.group(0)
+ if text[:1] == "<":
+ return "" # ignore tags
+ if text[:2] == "&#":
+ try:
+ if text[:3] == "&#x":
+ return unichr(int(text[3:-1], 16))
+ else:
+ return unichr(int(text[2:-1]))
+ except ValueError:
+ pass
+ elif text[:1] == "&":
+ import htmlentitydefs
+ entity = htmlentitydefs.entitydefs.get(text[1:-1])
+ if entity:
+ if entity[:2] == "&#":
+ try:
+ return unichr(int(entity[2:-1]))
+ except ValueError:
+ pass
+ else:
+ return unicode(entity, "iso-8859-1")
+ return text # leave as is
+ return re.sub("(?s)<[^>]*>|&#?\w+;", fixup, text)
+
+ def parsevalue(self,cr,uid,id,message,templateid,context):
+ #id: ID of the template's model's record to be used
+ #message: the complete text including placeholders
+ #templateid: the template id of the template
+ #context: TODO
+ #print cr,uid,id,message,templateid,context
+ if message:
+ logger = netsvc.Logger()
+ def merge(match):
+ template = self.pool.get("email.template").browse(cr,uid,templateid,context)
+ obj_pool = self.pool.get(template.object_name.model)
+ obj = obj_pool.browse(cr, uid, id, context)
+ exp = str(match.group()[2:-2]).strip()
+ #print "level 1:",exp
+ exp_spl = exp.split('/')
+ #print "level 2:",exp_spl
+ try:
+ result = eval(exp_spl[0], {'object':obj,})
+ except:
+ result = "Rendering Error"
+ #print "result:",result
+ try:
+ if result in (None, False):
+ if len(exp_spl)>1:
+ return exp_spl[1]
+ else:
+ return 'Not Available'
+ return str(result)
+ except:
+ return "Rendering Error"
+ if message:
+ com = re.compile('(\[\[.+?\]\])')
+ retmessage = com.sub(merge, message)
+ else:
+ retmessage=""
+ return retmessage
+
+email_template_engines()
diff --git a/addons/email_template/email_template_mailbox.py b/addons/email_template/email_template_mailbox.py
new file mode 100755
index 00000000000..1934f4e0227
--- /dev/null
+++ b/addons/email_template/email_template_mailbox.py
@@ -0,0 +1,182 @@
+from osv import osv, fields
+import time
+import email_template_engines
+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 Open ERP Scheduler
+ to periodically send emails
+ """
+ try:
+ self.send_all_mail(cursor, user, context)
+ except Exception, e:
+ LOGGER.notifyChannel(
+ _("Email Template"),
+ netsvc.LOG_ERROR,
+ _("Error sending mail: %s" % str(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):
+ if ids is None:
+ ids = []
+ for id in ids:
+ 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 = self.pool.get('ir.attachment').browse(cr, uid, attid, context)#,['datas_fname','datas'])
+ payload[attachment.datas_fname] = attachment.datas
+ print "233333333333333"
+ result = account_obj.send_mail(cr, uid,
+ [values['account_id'][0]],
+ {'To':values.get('email_to', u'') or u'', 'CC':values.get('email_cc', u'') or u'', 'BCC':values.get('email_bcc', u'') or u''},
+ values['subject'] or u'',
+ {'text':values.get('body_text', u'') or u'', 'html':values.get('body_html', u'') or u''},
+ payload=payload, context=context)
+
+ if result == True:
+ 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:
+ self.historise(cr, uid, [id], result, context)
+ except Exception, error:
+ logger = netsvc.Logger()
+ logger.notifyChannel(_("Power Email"), 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 True
+
+ 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(
+ 'Recepient (To)',
+ size=250,),
+ 'email_cc':fields.char(
+ ' CC',
+ size=250),
+ 'email_bcc':fields.char(
+ ' BCC',
+ size=250),
+ 'subject':fields.char(
+ ' Subject',
+ size=200,),
+ 'body_text':fields.text(
+ 'Standard Body (Text)'),
+ 'body_html':fields.text(
+ 'Body (Text-Web Client 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'),
+ 'history':fields.text(
+ 'History',
+ readonly=True,
+ store=True)
+ }
+
+ _defaults = {
+ 'state': lambda * a: 'na',
+ 'folder': lambda * a: 'outbox',
+ }
+
+ def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
+ if context is None:
+ context = {}
+ if context.get('company', False):
+ users_groups = self.pool.get('res.users').browse(cr, uid, uid, context).groups_id
+ group_acc_rel = {}
+ #get all accounts and get a table of {group1:[account1,account2],group2:[account1]}
+ for each_account_id in self.pool.get('email_template.account').search(cr, uid, [('state', '=', 'approved'), ('company', '=', 'yes')], context=context):
+ account = self.pool.get('email_template.account').browse(cr, uid, each_account_id, context)
+ for each_group in account.allowed_groups:
+ if not account.id in group_acc_rel.get(each_group, []):
+ groups = group_acc_rel.get(each_group, [])
+ groups.append(account.id)
+ group_acc_rel[each_group] = groups
+ users_company_accounts = []
+ for each_group in group_acc_rel.keys():
+ if each_group in users_groups:
+ for each_account in group_acc_rel[each_group]:
+ if not each_account in users_company_accounts:
+ users_company_accounts.append(each_account)
+ args.append(('account_id', 'in', users_company_accounts))
+ return super(osv.osv, self).search(cr, uid, args, offset, limit,
+ order, context=context, count=count)
+
+email_template_mailbox()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/email_template/email_template_mailbox_view.xml b/addons/email_template/email_template_mailbox_view.xml
new file mode 100755
index 00000000000..e6ff86d1087
--- /dev/null
+++ b/addons/email_template/email_template_mailbox_view.xml
@@ -0,0 +1,170 @@
+<?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="Outbox">
+ <group col="4" colspan="2">
+ <field name="email_from" colspan="4" select="1"/>
+ <field name="email_cc" colspan="4" select="1"/>
+ <field name="date_mail" colspan="4" select="2"/>
+ </group>
+ <group col="4" colspan="2">
+ <field name="email_to" colspan="4" required="1" select="1" />
+ <field name="email_bcc" colspan="4" 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" />
+ <!--<label string="Note: HTML body can't be edited with GTK desktop client." colspan="4"/>
+ --></page>
+
+ </notebook>
+ </page>
+
+
+ <page string="Attachments">
+ <group col="4">
+ <separator colspan="4" string="Attachments" />
+ <field name="attachments_ids" colspan="4" nolabel="1" />
+ </group>
+ </page>
+ <page string="Advanced">
+ <group col="4">
+ <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"/>
+ <separator string="History" colspan="4" />
+ <field name="history" nolabel="1" colspan="4"/>
+ </group>
+ </page>
+ </notebook>
+ <separator colspan="4" string="" />
+ <group col="4" colspan="4">
+ <field name="state" colspan="2" readonly="1" />
+ <button name="complete_mail" type="object" string="Download Full Mail" colspan="2" states="read,unread" />
+ <button name="send_this_mail" type="object" string="Send Mail" />
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <!--============================================= TREE VIEWS =============================================-->
+ <!--DRAFTS-->
+ <record model="ir.ui.view" id="email_template_drafts_tree">
+ <field name="name">email_template.mailbox.draftstree</field>
+ <field name="model">email_template.mailbox</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Drafts">
+ <field name="user" />
+ <field name="email_from" select="1" />
+ <field name="subject" select="1" />
+ <field name="attachments_ids" select="2" />
+ <field name="date_mail" select="2" />
+ </tree>
+ </field>
+ </record>
+ <!--OUTBOX-->
+ <record model="ir.ui.view" id="email_template_outbox_tree">
+ <field name="name">email_template.mailbox.outboxtree</field>
+ <field name="model">email_template.mailbox</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Outbox">
+ <field name="user" />
+ <field name="email_from" select="1" />
+ <field name="subject" select="1" />
+ <field name="attachments_ids" select="2" />
+ <field name="date_mail" select="2" />
+ </tree>
+ </field>
+ </record>
+ <!--SENT-->
+ <record model="ir.ui.view" id="email_template_sentbox_tree">
+ <field name="name">email_template.mailbox.sentboxtree</field>
+ <field name="model">email_template.mailbox</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Sent">
+ <field name="user" />
+ <field name="email_from" select="1" />
+ <field name="subject" select="1" />
+ <field name="attachments_ids" select="2" />
+ <field name="date_mail" select="2" />
+ </tree>
+ </field>
+ </record>
+ <!--TRASH-->
+ <record model="ir.ui.view" id="email_template_trashbox_tree">
+ <field name="name">email_template.mailbox.trashboxtree</field>
+ <field name="model">email_template.mailbox</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Trash">
+ <field name="user" />
+ <field name="email_from" select="1" />
+ <field name="subject" select="1" />
+ <field name="attachments_ids" select="2" />
+ <field name="date_mail" select="2" />
+ </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="Mailboxes">
+ <filter icon="terp-crm" string="Drafts" name="draft" domain="[('folder','=','drafts']"/>
+ <filter icon="terp-crm" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
+ <separator orientation="vertical"/>
+ <filter icon="terp-crm" string="Sent" domain="[('folder','=','sent')]"/>
+ <filter icon="terp-crm" string="Trash" domain="[('folder','=','trash')]"/>
+ <separator orientation="vertical"/>
+ <filter icon="terp-crm" string="Not Applicable" domain="[('state','=','na')]"/>
+ <filter icon="terp-crm" string="Sending" domain="[('state','=','sending')]"/>
+ <separator orientation="vertical"/>
+ <field name="email_from" select="1"/>
+ <field name="email_to" select="1"/>
+ <field name="subject" select="1"/>
+ </search>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_email_template_mailbox">
+ <field name="name">Mailbox</field>
+ <field name="res_model">email_template.mailbox</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form,tree</field>
+ <field name="view_id" ref="email_template_outbox_tree" />
+ <field name="context">{'group_by': [], 'search_default_draft': 1, 'search_default_outbox': 1}</field>
+ <field name="search_view_id" ref="view_email_template_mailbox_search"/>
+ </record>
+
+ <!--======================================== MENUS ========================================-->
+ <menuitem name="MailBox" id="menu_email_template_mailbox_all_main2" parent="menu_email_template" />
+ <menuitem name="Personal" id="menu_email_template_personal" parent="menu_email_template_mailbox_all_main2" />
+ <menuitem name="Mails" id="menu_email_template_personal_mails" parent="menu_email_template_personal" action="action_email_template_mailbox"/>
+ <menuitem name="Company" id="menu_email_template_company" parent="menu_email_template_mailbox_all_main2" />
+ <menuitem name="Mails" id="menu_email_template_company_mails" parent="menu_email_template_company" action="action_email_template_mailbox"/>
+
+ </data>
+</openerp>
+
+
+
+
diff --git a/addons/email_template/email_template_scheduler_data.xml b/addons/email_template/email_template_scheduler_data.xml
new file mode 100755
index 00000000000..30d69f99398
--- /dev/null
+++ b/addons/email_template/email_template_scheduler_data.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data noupdate="1">
+ <record forcecreate="True" id="ir_cron_mail_scheduler_action" model="ir.cron">
+ <field name="name">Email Template scheduler</field>
+ <field name="user_id" ref="base.user_root"/>
+ <field name="interval_number">1</field>
+ <field name="interval_type">hours</field>
+ <field name="numbercall">12</field>
+ <field eval="False" name="doall"/>
+ <field eval="'email_template.mailbox'" name="model"/>
+ <field eval="'run_mail_scheduler'" name="function"/>
+ <field eval="'()'" name="args"/>
+ </record>
+ </data>
+</openerp>
diff --git a/addons/email_template/email_template_view.xml b/addons/email_template/email_template_view.xml
new file mode 100755
index 00000000000..8e14a861edc
--- /dev/null
+++ b/addons/email_template/email_template_view.xml
@@ -0,0 +1,188 @@
+<?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="rel_model" />
+ <newline />
+ <field name="rel_model_ref" on_change="on_change_ref(rel_model_ref, context)" />
+ <newline />
+ <field name="to" />
+ <newline />
+ <field name="cc" />
+ <newline />
+ <field name="bcc" />
+ <newline />
+ <field name="subject" />
+ <newline />
+ <field name="body_text" />
+ <newline />
+ <!-- <field name="body_html" widget="text_html" />-->
+ <!--
+ Removed text_html because it doesnt work in GTK
+ And TinyMCE messes up the HTML in Web Client
+ -->
+ <field name="body_html"/>
+ <newline />
+ <field name="report" />
+ <group>
+ <button icon="gtk-ok" special="cancel" string="OK" />
+ </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">{'ids':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" />
+ <notebook colspan="4">
+ <page string="Mail Details">
+ <group col="4" colspan="2">
+ <field name="def_to" colspan="4" required="1" />
+ <field name="def_cc" colspan="4" />
+ <field name="def_bcc" colspan="4" />
+ </group>
+ <group col="2" colspan="2">
+ <field name="def_subject" colspan="4" required="1" />
+ <field name="use_sign" colspan="4" />
+ <field name="lang" colspan="4" />
+ </group>
+ <separator colspan="3" string="Standard Body" />
+ <separator colspan="1" string="Expression Builder" />
+
+ <notebook>
+ <page string="Body (Text)">
+ <field name="def_body_text" colspan="4" 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>
+ </notebook>
+ <group col="4">
+ <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">
+
+ <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" />
+ <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)" />
+ <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" />
+ </page>
+ </notebook>
+ <button name="%(wizard_email_template_preview)d" string="Preview Template"
+ type="action" colspan="4" target="new" />
+ </group>
+ </page>
+ <page string="Security">
+ <separator colspan="4" string="Allowed User Groups" />
+ <field name="allowed_groups" string="Allowed User Groups"
+ nolabel="1" />
+ </page>
+ <page string="Advanced">
+ <separator string="Automatic Email" colspan="4" />
+ <field name="enforce_from_account" attrs="{'required':[('auto_email','=',True)]}" />
+ <newline/>
+ <field name="ref_ir_act_window" />
+ <field name="ref_ir_value" />
+ <separator string="Attachments (Report to attach)" colspan="4"/>
+ <field name="file_name" colspan="2" />
+ <field name="report_template" colspan="2"
+ domain="[('model','=',model_int_name)]" />
+ </page>
+ </notebook>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.ui.view" id="email_template_tree">
+ <field name="name">email.template.tree</field>
+ <field name="model">email.template</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Email Templates">
+ <field name="name" select="1" />
+ <field name="object_name" required="1" select="1" />
+ <field name="def_to" colspan="4" select="2" />
+ <field name="def_cc" colspan="4" select="2" />
+ <field name="def_bcc" colspan="4" select="2" />
+ <field name="def_subject" colspan="4" select="2" />
+ <field name="use_sign" colspan="4" select="2" />
+ <field name="file_name" colspan="4" />
+ <field name="enforce_from_account" />
+ </tree>
+ </field>
+ </record>
+
+ <record id="view_email_template_search" model="ir.ui.view">
+ <field name="name">email.template.search</field>
+ <field name="model">email.template</field>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Templates">
+ <separator orientation="vertical"/>
+ <field name="name" select="1"/>
+ <field name="object_name" select="1"/>
+ <field name="def_to" select="1"/>
+ <separator orientation="vertical"/>
+ <field name="lang" select="1"/>
+ <field name="def_subject" select="1"/>
+ <field name="file_name" select="1"/>
+ </search>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_email_template_tree_all">
+ <field name="name">Email Templates</field>
+ <field name="res_model">email.template</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form,tree</field>
+ <field name="view_id" ref="email_template_tree" />
+ <field name="search_view_id" ref="view_email_template_search"/>
+ </record>
+
+ <menuitem name="E-MAIL Templates" id="menu_email_template_all"
+ parent="menu_email_template_configuration" action="action_email_template_tree_all" />
+
+ </data>
+</openerp>
+
+
+
+
+
diff --git a/addons/email_template/email_template_workflow.xml b/addons/email_template/email_template_workflow.xml
new file mode 100755
index 00000000000..4d3176f0ae0
--- /dev/null
+++ b/addons/email_template/email_template_workflow.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <record id="PE_ADMIN" model="res.roles">
+ <field name="name">Email Administrator</field>
+ </record>
+
+ <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>
+ <field name="role_id" ref="PE_ADMIN"/>
+ </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>
+ <field name="role_id" ref="PE_ADMIN"/>
+ </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>
+ <field name="role_id" ref="PE_ADMIN"/>
+ </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>
+ <field name="role_id" ref="PE_ADMIN"/>
+ </record>
+ </data>
+</openerp>
diff --git a/addons/email_template/html2text.py b/addons/email_template/html2text.py
new file mode 100755
index 00000000000..f8be00adf0f
--- /dev/null
+++ b/addons/email_template/html2text.py
@@ -0,0 +1,455 @@
+#!/usr/bin/env python
+"""html2text: Turn HTML into equivalent Markdown-structured text."""
+__version__ = "2.36"
+__author__ = "Aaron Swartz (me@aaronsw.com)"
+__copyright__ = "(C) 2004-2008 Aaron Swartz. GNU GPL 3."
+__contributors__ = ["Martin 'Joey' Schulze", "Ricardo Reyes", "Kevin Jay North"]
+
+# TODO:
+# Support decoded entities with unifiable.
+
+if not hasattr(__builtins__, 'True'): True, False = 1, 0
+import re, sys, urllib, htmlentitydefs, codecs, StringIO, types
+import sgmllib
+import urlparse
+sgmllib.charref = re.compile('&#([xX]?[0-9a-fA-F]+)[^0-9a-fA-F]')
+
+try: from textwrap import wrap
+except: pass
+
+# Use Unicode characters instead of their ascii psuedo-replacements
+UNICODE_SNOB = 0
+
+# Put the links after each paragraph instead of at the end.
+LINKS_EACH_PARAGRAPH = 0
+
+# Wrap long lines at position. 0 for no wrapping. (Requires Python 2.3.)
+BODY_WIDTH = 78
+
+# Don't show internal links (href="#local-anchor") -- corresponding link targets
+# won't be visible in the plain text file anyway.
+SKIP_INTERNAL_LINKS = False
+
+### Entity Nonsense ###
+
+def name2cp(k):
+ if k == 'apos': return ord("'")
+ if hasattr(htmlentitydefs, "name2codepoint"): # requires Python 2.3
+ return htmlentitydefs.name2codepoint[k]
+ else:
+ k = htmlentitydefs.entitydefs[k]
+ if k.startswith("&#") and k.endswith(";"): return int(k[2:-1]) # not in latin-1
+ return ord(codecs.latin_1_decode(k)[0])
+
+unifiable = {'rsquo':"'", 'lsquo':"'", 'rdquo':'"', 'ldquo':'"',
+'copy':'(C)', 'mdash':'--', 'nbsp':' ', 'rarr':'->', 'larr':'<-', 'middot':'*',
+'ndash':'-', 'oelig':'oe', 'aelig':'ae',
+'agrave':'a', 'aacute':'a', 'acirc':'a', 'atilde':'a', 'auml':'a', 'aring':'a',
+'egrave':'e', 'eacute':'e', 'ecirc':'e', 'euml':'e',
+'igrave':'i', 'iacute':'i', 'icirc':'i', 'iuml':'i',
+'ograve':'o', 'oacute':'o', 'ocirc':'o', 'otilde':'o', 'ouml':'o',
+'ugrave':'u', 'uacute':'u', 'ucirc':'u', 'uuml':'u'}
+
+unifiable_n = {}
+
+for k in unifiable.keys():
+ unifiable_n[name2cp(k)] = unifiable[k]
+
+def charref(name):
+ if name[0] in ['x','X']:
+ c = int(name[1:], 16)
+ else:
+ c = int(name)
+
+ if not UNICODE_SNOB and c in unifiable_n.keys():
+ return unifiable_n[c]
+ else:
+ return unichr(c)
+
+def entityref(c):
+ if not UNICODE_SNOB and c in unifiable.keys():
+ return unifiable[c]
+ else:
+ try: name2cp(c)
+ except KeyError: return "&" + c
+ else: return unichr(name2cp(c))
+
+def replaceEntities(s):
+ s = s.group(1)
+ if s[0] == "#":
+ return charref(s[1:])
+ else: return entityref(s)
+
+r_unescape = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
+def unescape(s):
+ return r_unescape.sub(replaceEntities, s)
+
+def fixattrs(attrs):
+ # Fix bug in sgmllib.py
+ if not attrs: return attrs
+ newattrs = []
+ for attr in attrs:
+ newattrs.append((attr[0], unescape(attr[1])))
+ return newattrs
+
+### End Entity Nonsense ###
+
+def onlywhite(line):
+ """Return true if the line does only consist of whitespace characters."""
+ for c in line:
+ if c is not ' ' and c is not ' ':
+ return c is ' '
+ return line
+
+def optwrap(text):
+ """Wrap all paragraphs in the provided text."""
+ if not BODY_WIDTH:
+ return text
+
+ assert wrap, "Requires Python 2.3."
+ result = ''
+ newlines = 0
+ for para in text.split("\n"):
+ if len(para) > 0:
+ if para[0] is not ' ' and para[0] is not '-' and para[0] is not '*':
+ for line in wrap(para, BODY_WIDTH):
+ result += line + "\n"
+ result += "\n"
+ newlines = 2
+ else:
+ if not onlywhite(para):
+ result += para + "\n"
+ newlines = 1
+ else:
+ if newlines < 2:
+ result += "\n"
+ newlines += 1
+ return result
+
+def hn(tag):
+ if tag[0] == 'h' and len(tag) == 2:
+ try:
+ n = int(tag[1])
+ if n in range(1, 10): return n
+ except ValueError: return 0
+
+class _html2text(sgmllib.SGMLParser):
+ def __init__(self, out=sys.stdout.write, baseurl=''):
+ sgmllib.SGMLParser.__init__(self)
+
+ if out is None: self.out = self.outtextf
+ else: self.out = out
+ self.outtext = u''
+ self.quiet = 0
+ self.p_p = 0
+ self.outcount = 0
+ self.start = 1
+ self.space = 0
+ self.a = []
+ self.astack = []
+ self.acount = 0
+ self.list = []
+ self.blockquote = 0
+ self.pre = 0
+ self.startpre = 0
+ self.lastWasNL = 0
+ self.abbr_title = None # current abbreviation definition
+ self.abbr_data = None # last inner HTML (for abbr being defined)
+ self.abbr_list = {} # stack of abbreviations to write later
+ self.baseurl = baseurl
+
+ def outtextf(self, s):
+ self.outtext += s
+
+ def close(self):
+ sgmllib.SGMLParser.close(self)
+
+ self.pbr()
+ self.o('', 0, 'end')
+
+ return self.outtext
+
+ def handle_charref(self, c):
+ self.o(charref(c))
+
+ def handle_entityref(self, c):
+ self.o(entityref(c))
+
+ def unknown_starttag(self, tag, attrs):
+ self.handle_tag(tag, attrs, 1)
+
+ def unknown_endtag(self, tag):
+ self.handle_tag(tag, None, 0)
+
+ def previousIndex(self, attrs):
+ """ returns the index of certain set of attributes (of a link) in the
+ self.a list
+
+ If the set of attributes is not found, returns None
+ """
+ if not attrs.has_key('href'): return None
+
+ i = -1
+ for a in self.a:
+ i += 1
+ match = 0
+
+ if a.has_key('href') and a['href'] == attrs['href']:
+ if a.has_key('title') or attrs.has_key('title'):
+ if (a.has_key('title') and attrs.has_key('title') and
+ a['title'] == attrs['title']):
+ match = True
+ else:
+ match = True
+
+ if match: return i
+
+ def handle_tag(self, tag, attrs, start):
+ attrs = fixattrs(attrs)
+
+ if hn(tag):
+ self.p()
+ if start: self.o(hn(tag)*"#" + ' ')
+
+ if tag in ['p', 'div']: self.p()
+
+ if tag == "br" and start: self.o(" \n")
+
+ if tag == "hr" and start:
+ self.p()
+ self.o("* * *")
+ self.p()
+
+ if tag in ["head", "style", 'script']:
+ if start: self.quiet += 1
+ else: self.quiet -= 1
+
+ if tag in ["body"]:
+ self.quiet = 0 # sites like 9rules.com never close <head>
+
+ if tag == "blockquote":
+ if start:
+ self.p(); self.o('> ', 0, 1); self.start = 1
+ self.blockquote += 1
+ else:
+ self.blockquote -= 1
+ self.p()
+
+ if tag in ['em', 'i', 'u']: self.o("_")
+ if tag in ['strong', 'b']: self.o("**")
+ if tag == "code" and not self.pre: self.o('`') #TODO: `` `this` ``
+ if tag == "abbr":
+ if start:
+ attrsD = {}
+ for (x, y) in attrs: attrsD[x] = y
+ attrs = attrsD
+
+ self.abbr_title = None
+ self.abbr_data = ''
+ if attrs.has_key('title'):
+ self.abbr_title = attrs['title']
+ else:
+ if self.abbr_title != None:
+ self.abbr_list[self.abbr_data] = self.abbr_title
+ self.abbr_title = None
+ self.abbr_data = ''
+
+ if tag == "a":
+ if start:
+ attrsD = {}
+ for (x, y) in attrs: attrsD[x] = y
+ attrs = attrsD
+ if attrs.has_key('href') and not (SKIP_INTERNAL_LINKS and attrs['href'].startswith('#')):
+ self.astack.append(attrs)
+ self.o("[")
+ else:
+ self.astack.append(None)
+ else:
+ if self.astack:
+ a = self.astack.pop()
+ if a:
+ i = self.previousIndex(a)
+ if i is not None:
+ a = self.a[i]
+ else:
+ self.acount += 1
+ a['count'] = self.acount
+ a['outcount'] = self.outcount
+ self.a.append(a)
+ self.o("][" + `a['count']` + "]")
+
+ if tag == "img" and start:
+ attrsD = {}
+ for (x, y) in attrs: attrsD[x] = y
+ attrs = attrsD
+ if attrs.has_key('src'):
+ attrs['href'] = attrs['src']
+ alt = attrs.get('alt', '')
+ i = self.previousIndex(attrs)
+ if i is not None:
+ attrs = self.a[i]
+ else:
+ self.acount += 1
+ attrs['count'] = self.acount
+ attrs['outcount'] = self.outcount
+ self.a.append(attrs)
+ self.o("![")
+ self.o(alt)
+ self.o("]["+`attrs['count']`+"]")
+
+ if tag == 'dl' and start: self.p()
+ if tag == 'dt' and not start: self.pbr()
+ if tag == 'dd' and start: self.o(' ')
+ if tag == 'dd' and not start: self.pbr()
+
+ if tag in ["ol", "ul"]:
+ if start:
+ self.list.append({'name':tag, 'num':0})
+ else:
+ if self.list: self.list.pop()
+
+ self.p()
+
+ if tag == 'li':
+ if start:
+ self.pbr()
+ if self.list: li = self.list[-1]
+ else: li = {'name':'ul', 'num':0}
+ self.o(" "*len(self.list)) #TODO: line up <ol><li>s > 9 correctly.
+ if li['name'] == "ul": self.o("* ")
+ elif li['name'] == "ol":
+ li['num'] += 1
+ self.o(`li['num']`+". ")
+ self.start = 1
+ else:
+ self.pbr()
+
+ if tag in ["table", "tr"] and start: self.p()
+ if tag == 'td': self.pbr()
+
+ if tag == "pre":
+ if start:
+ self.startpre = 1
+ self.pre = 1
+ else:
+ self.pre = 0
+ self.p()
+
+ def pbr(self):
+ if self.p_p == 0: self.p_p = 1
+
+ def p(self): self.p_p = 2
+
+ def o(self, data, puredata=0, force=0):
+ if self.abbr_data is not None: self.abbr_data += data
+
+ if not self.quiet:
+ if puredata and not self.pre:
+ data = re.sub('\s+', ' ', data)
+ if data and data[0] == ' ':
+ self.space = 1
+ data = data[1:]
+ if not data and not force: return
+
+ if self.startpre:
+ #self.out(" :") #TODO: not output when already one there
+ self.startpre = 0
+
+ bq = (">" * self.blockquote)
+ if not (force and data and data[0] == ">") and self.blockquote: bq += " "
+
+ if self.pre:
+ bq += " "
+ data = data.replace("\n", "\n"+bq)
+
+ if self.start:
+ self.space = 0
+ self.p_p = 0
+ self.start = 0
+
+ if force == 'end':
+ # It's the end.
+ self.p_p = 0
+ self.out("\n")
+ self.space = 0
+
+
+ if self.p_p:
+ self.out(('\n'+bq)*self.p_p)
+ self.space = 0
+
+ if self.space:
+ if not self.lastWasNL: self.out(' ')
+ self.space = 0
+
+ if self.a and ((self.p_p == 2 and LINKS_EACH_PARAGRAPH) or force == "end"):
+ if force == "end": self.out("\n")
+
+ newa = []
+ for link in self.a:
+ if self.outcount > link['outcount']:
+ self.out(" ["+`link['count']`+"]: " + urlparse.urljoin(self.baseurl, link['href']))
+ if link.has_key('title'): self.out(" ("+link['title']+")")
+ self.out("\n")
+ else:
+ newa.append(link)
+
+ if self.a != newa: self.out("\n") # Don't need an extra line when nothing was done.
+
+ self.a = newa
+
+ if self.abbr_list and force == "end":
+ for abbr, definition in self.abbr_list.items():
+ self.out(" *[" + abbr + "]: " + definition + "\n")
+
+ self.p_p = 0
+ self.out(data)
+ self.lastWasNL = data and data[-1] == '\n'
+ self.outcount += 1
+
+ def handle_data(self, data):
+ if r'\/script>' in data: self.quiet -= 1
+ self.o(data, 1)
+
+ def unknown_decl(self, data): pass
+
+def wrapwrite(text): sys.stdout.write(text.encode('utf8'))
+
+def html2text_file(html, out=wrapwrite, baseurl=''):
+ h = _html2text(out, baseurl)
+ h.feed(html)
+ h.feed("")
+ return h.close()
+
+def html2text(html, baseurl=''):
+ return optwrap(html2text_file(html, None, baseurl))
+
+if __name__ == "__main__":
+ baseurl = ''
+ if sys.argv[1:]:
+ arg = sys.argv[1]
+ if arg.startswith('http://'):
+ baseurl = arg
+ j = urllib.urlopen(baseurl)
+ try:
+ from feedparser import _getCharacterEncoding as enc
+ except ImportError:
+ enc = lambda x, y: ('utf-8', 1)
+ text = j.read()
+ encoding = enc(j.headers, text)[0]
+ if encoding == 'us-ascii': encoding = 'utf-8'
+ data = text.decode(encoding)
+
+ else:
+ encoding = 'utf8'
+ if len(sys.argv) > 2:
+ encoding = sys.argv[2]
+ f = open(arg, 'r')
+ try:
+ data = f.read().decode(encoding)
+ finally:
+ f.close()
+ else:
+ data = sys.stdin.read().decode('utf8')
+ wrapwrite(html2text(data, baseurl))
+
diff --git a/addons/email_template/security/email_template_security.xml b/addons/email_template/security/email_template_security.xml
new file mode 100755
index 00000000000..90067252eca
--- /dev/null
+++ b/addons/email_template/security/email_template_security.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data noupdate="0">
+
+ <record id="res_groups_email_template_manager" model="res.groups">
+ <field name="name">Email Template / Settings_Manager</field>
+ </record>
+
+ <record id="res_groups_email_template_userse" model="res.groups">
+ <field name="name">Email Template / External_users</field>
+ </record>
+
+ <record id="res_groups_email_template_usersi" model="res.groups">
+ <field name="name">Email Template / Internal_users</field>
+ </record>
+
+
+ </data>
+</openerp>
diff --git a/addons/email_template/wizard/__init__.py b/addons/email_template/wizard/__init__.py
new file mode 100755
index 00000000000..ea6fcfbcd86
--- /dev/null
+++ b/addons/email_template/wizard/__init__.py
@@ -0,0 +1 @@
+import email_template_send_wizard
diff --git a/addons/email_template/wizard/email_template_send_wizard.py b/addons/email_template/wizard/email_template_send_wizard.py
new file mode 100755
index 00000000000..7d27eab9adf
--- /dev/null
+++ b/addons/email_template/wizard/email_template_send_wizard.py
@@ -0,0 +1,235 @@
+from osv import osv, fields
+from mako.template import Template
+from mako import exceptions
+import netsvc
+import base64
+import time
+from tools.translate import _
+import tools
+from email_template.email_template import get_value
+
+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.enforce_from_account:
+ return [(template.enforce_from_account.id, '%s (%s)' % (template.enforce_from_account.name, template.enforce_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(_("Power Email"), 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 power email account."))
+ raise osv.except_osv(_("Power Email"),_("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal power 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):
+ 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,),
+ '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'),
+ }
+
+ _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,
+ 'requested':lambda self,cr,uid,ctx: len(ctx['src_rec_ids']),
+ 'full_success': lambda *a: False
+ }
+
+ def fields_get(self, cr, uid, fields=None, context=None, read_access=True):
+ result = super(email_template_send_wizard, self).fields_get(cr, uid, fields, context, read_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)
+ 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(_("Power Email"), 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(_("Power Email"),_("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
+
+ mail_ids = []
+ template = self._get_template(cr, uid, context)
+ for id in context['src_rec_ids']:
+ print "@22222222222222222222222",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:
diff --git a/addons/email_template/wizard/email_template_send_wizard_view.xml b/addons/email_template/wizard/email_template_send_wizard_view.xml
new file mode 100755
index 00000000000..5f2f1641e31
--- /dev/null
+++ b/addons/email_template/wizard/email_template_send_wizard_view.xml
@@ -0,0 +1,64 @@
+<?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" />
+ <!--<label string="Note: HTML body can't be edited with GTK desktop client." colspan="4"/>
+ --></page>
+ <page string="Attachments">
+ <label string="Add here all attachments of the current document you want to include in the e-mail." 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>
+
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index 277099aca02..65d5db06fe3 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -2,6 +2,12 @@
<openerp>
<data>
+ <menuitem
+ id="menu_hr_config_applicant"
+ name="Applicant"
+ parent="hr.menu_hr_configuration"
+ />
+
# ------------------------------------------------------
# Job Categories
# ------------------------------------------------------
@@ -25,7 +31,8 @@
<field name="domain">[('object_id.model', '=', 'hr.applicant')]</field>
<field name="context">{'object_id':'hr.applicant'}</field>
</record>
- <menuitem action="hr_job_stage_act" id="menu_hr_job_stage_act" parent="crm.menu_crm_case_stage"/>
+
+ <menuitem action="hr_job_stage_act" id="menu_hr_job_stage_act" name="Stages" parent="menu_hr_config_applicant"/>
# ------------------------------------------------------
# Jobs
diff --git a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
index eccdb721de0..880e5837fd2 100644
--- a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
+++ b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
@@ -462,6 +462,7 @@
<newline/>
<group expand="1" string="Group By...">
<filter string="User" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
+ <separator orientation="vertical"/>
<filter string="Product" icon="terp-project" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Analytic Account" icon="terp-project" domain="[]" context="{'group_by':'analytic_account_id'}"/>
<filter string="General Account" icon="terp-project" domain="[]" context="{'group_by':'general_account_id'}"/>
diff --git a/addons/hr_timesheet_sheet/report/timesheet_report_view.xml b/addons/hr_timesheet_sheet/report/timesheet_report_view.xml
index c7cf7b0495e..32e8bda4f7f 100644
--- a/addons/hr_timesheet_sheet/report/timesheet_report_view.xml
+++ b/addons/hr_timesheet_sheet/report/timesheet_report_view.xml
@@ -74,12 +74,12 @@
domain="[('user_id','=',False)]"/>
</field>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
- </group>
- <newline/>
+ </group>
+ <newline/>
<group expand="1" string="Group By...">
<filter string="User" name="User" icon="terp-hr" context="{'group_by':'user_id'}"/>
- <filter string="Product" icon="terp-hr" context="{'group_by':'product_id'}"/>
<separator orientation="vertical"/>
+ <filter string="Product" icon="terp-hr" context="{'group_by':'product_id'}"/>
<filter string="Type of Invoicing" icon="terp-hr" context="{'group_by':'to_invoice'}"/>
<filter string="Analytic Account" icon="terp-hr" context="{'group_by':'account_id'}"/>
<filter string="General Account" icon="terp-hr" context="{'group_by':'general_account_id'}"/>
@@ -111,7 +111,7 @@
<separator orientation="vertical"/>
<field name="general_account_id"/>
<field name="to_invoice" widget="selection"/>
- </group>
+ </group>
</search>
</field>
</record>
diff --git a/addons/mail_gateway/mail_gateway_view.xml b/addons/mail_gateway/mail_gateway_view.xml
index 5cf35fa3420..611416055f7 100644
--- a/addons/mail_gateway/mail_gateway_view.xml
+++ b/addons/mail_gateway/mail_gateway_view.xml
@@ -8,32 +8,32 @@
<field name="arch" type="xml">
<form string="mailgate message">
<group colspan="4" col="6">
- <field name="name" required="1" select="1"/>
- <field name="date" required="1" select="1"/>
- <field name="user_id" string="Responsible" select="1"/>
- </group>
+ <field name="name" required="1" select="1"/>
+ <field name="date" required="1" select="1"/>
+ <field name="user_id" string="Responsible" select="1"/>
+ </group>
<notebook colspan="4">
- <page string="Details">
- <group col="4" colspan="4">
- <separator string="Email Details" colspan="4"/>
- <field name="email_from" />
- <field name="email_to" />
- <field name="email_cc" />
- <field name="email_bcc" />
- <field name="message_id" />
- </group>
- <separator string="Description" colspan="4"/>
+ <page string="Details">
+ <group col="4" colspan="4">
+ <separator string="Email Details" colspan="4"/>
+ <field name="email_from" />
+ <field name="email_to" />
+ <field name="email_cc" />
+ <field name="email_bcc" />
+ <field name="message_id" />
+ </group>
+ <separator string="Description" colspan="4"/>
<field name="description" nolabel="1" colspan="4" />
- </page>
- <page string="Attachments">
- <separator string="Attachments" colspan="4"/>
- <field name="attachment_ids" nolabel="1" colspan="4" readonly="1"/>
- </page>
- </notebook>
+ </page>
+ <page string="Attachments">
+ <separator string="Attachments" colspan="4"/>
+ <field name="attachment_ids" nolabel="1" colspan="4" readonly="1"/>
+ </page>
+ </notebook>
</form>
</field>
</record>
-
+
<record model="ir.ui.view" id="view_mailgate_message_tree">
<field name="name">mailgate.message.tree</field>
<field name="model">mailgate.message</field>
@@ -41,12 +41,12 @@
<field name="arch" type="xml">
<tree string="Mailgateway Message">
<field name="date" />
- <field name="email_from" />
- <field name="user_id" />
+ <field name="email_from" />
+ <field name="user_id" />
</tree>
</field>
</record>
-
+
<record model="ir.ui.view" id="view_mailgate_message_search">
<field name="name">mailgate.message.search</field>
<field name="model">mailgate.message</field>
@@ -56,11 +56,11 @@
<field name="name" />
<field name="date" />
<field name="user_id" />
- <field name="message_id" />
+ <field name="message_id" />
</search>
</field>
</record>
-
+
<record model="ir.ui.view" id="view_mailgate_thread_form">
<field name="name">mailgate.thread.form</field>
@@ -71,33 +71,33 @@
<field name="thread" select="1"/>
<separator string="Logs" colspan="4"/>
<field name="log_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
- <tree string="Mailgateway Logs">
- <field name="name" select="1" />
- <field name="date" />
- </tree>
- <form string="Mailgate Logs">
- <field name="name" />
- <field name="date" />
- <field name="user_id" />
- <field name="message_id" />
- <notebook colspan="4">
- <page string="Email Details">
- <group col="4" colspan="4">
- <separator string="Email Details" colspan="4"/>
- <field name="email_from" />
- <field name="email_to" />
- <field name="email_cc" />
- <field name="email_bcc" />
- </group>
- <separator string="Description" colspan="4"/>
+ <tree string="Mailgateway Logs">
+ <field name="name" select="1" />
+ <field name="date" />
+ </tree>
+ <form string="Mailgate Logs">
+ <field name="name" />
+ <field name="date" />
+ <field name="user_id" />
+ <field name="message_id" />
+ <notebook colspan="4">
+ <page string="Email Details">
+ <group col="4" colspan="4">
+ <separator string="Email Details" colspan="4"/>
+ <field name="email_from" />
+ <field name="email_to" />
+ <field name="email_cc" />
+ <field name="email_bcc" />
+ </group>
+ <separator string="Description" colspan="4"/>
<field name="description" nolabel="1" colspan="4" />
- </page>
- <page string="Attachments">
- <separator string="Attachments" colspan="4"/>
- <field name="attachment_ids" nolabel="1" colspan="4" />
- </page>
- </notebook>
- </form>
+ </page>
+ <page string="Attachments">
+ <separator string="Attachments" colspan="4"/>
+ <field name="attachment_ids" nolabel="1" colspan="4" />
+ </page>
+ </notebook>
+ </form>
</field>
<separator string="Histories" colspan="4"/>
<field name="message_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
@@ -131,7 +131,7 @@
</form>
</field>
</record>
-
+
<record model="ir.ui.view" id="view_mailgate_thread_tree">
<field name="name">mailgate.thread.tree</field>
<field name="model">mailgate.thread</field>
@@ -143,41 +143,41 @@
</tree>
</field>
</record>
-
+
<record model="ir.actions.act_window" id="action_view_mailgate_thread">
- <field name="name">Mailgateway Threads</field>
- <field name="res_model">mailgate.thread</field>
- <field name="view_mode">tree,form</field>
- <field name="view_type">form</field>
- <field name="view_id" ref="view_mailgate_thread_tree"/>
- </record>
-
- <record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view1">
- <field name="sequence" eval="1"/>
- <field name="view_mode">tree</field>
- <field name="view_id" ref="view_mailgate_thread_tree"/>
- <field name="act_window_id" ref="action_view_mailgate_thread"/>
- </record>
- <record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view2">
- <field name="sequence" eval="2"/>
- <field name="view_mode">form</field>
- <field name="view_id" ref="view_mailgate_thread_form"/>
- <field name="act_window_id" ref="action_view_mailgate_thread"/>
- </record>
-
-
- <!-- <menuitem id="base.menu_crm_configuration" name="Cases"
+ <field name="name">Mailgateway Threads</field>
+ <field name="res_model">mailgate.thread</field>
+ <field name="view_mode">tree,form</field>
+ <field name="view_type">form</field>
+ <field name="view_id" ref="view_mailgate_thread_tree"/>
+ </record>
+
+ <record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view1">
+ <field name="sequence" eval="1"/>
+ <field name="view_mode">tree</field>
+ <field name="view_id" ref="view_mailgate_thread_tree"/>
+ <field name="act_window_id" ref="action_view_mailgate_thread"/>
+ </record>
+ <record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view2">
+ <field name="sequence" eval="2"/>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="view_mailgate_thread_form"/>
+ <field name="act_window_id" ref="action_view_mailgate_thread"/>
+ </record>
+
+
+ <!-- <menuitem id="base.menu_crm_configuration" name="Cases"
parent="base.menu_base_config" sequence="0"/>
<menuitem id="menu_mailgate_thread" name="Mailgateway Threads" action="action_view_mailgate_thread"
- parent="base.menu_crm_configuration" sequence="20"/>
- -->
+ parent="base.menu_crm_configuration" sequence="20"/>
+ -->
<act_window domain="[('partner_id', '=', active_id), ('history', '=', True)]"
id="act_res_partner_emails" name="Emails"
res_model="mailgate.message"
src_model="res.partner"
- view_id="view_mailgate_message_tree"
+ view_id="view_mailgate_message_tree"
/>
</data>
-</openerp>
+</openerp> \ No newline at end of file
diff --git a/addons/marketing/marketing_view.xml b/addons/marketing/marketing_view.xml
index 7a72f39c6eb..cc6200537cf 100644
--- a/addons/marketing/marketing_view.xml
+++ b/addons/marketing/marketing_view.xml
@@ -14,20 +14,16 @@
<form position="attributes">
<attribute name="string">Marketing Modules Installation</attribute>
</form>
-
<separator string="title" position="attributes">
- <attribute name="string">Configure Your Marketing System</attribute>
+ <attribute name="string">Select Marketing Modules to Install</attribute>
</separator>
<xpath expr="//label[@string='description']"
position="attributes">
- <attribute name="string">You can enhance OpenERP's basic Marketing support with a few additional OpenERP applications</attribute>
+ <attribute name="string">OpenERP provides tools to automate your leads process, design marketing campaigns and profile efficiently your customers.</attribute>
</xpath>
<group colspan="8">
- <group colspan="2" col="2">
- <separator string="Marketing Mdules" colspan="4" />
<field name="marketing_campaign" />
<field name="crm_profiling" />
- </group>
</group>
</data>
</field>
@@ -49,4 +45,4 @@
</record>
</data>
-</openerp> \ No newline at end of file
+</openerp>
diff --git a/addons/marketing/marketing_wizard.py b/addons/marketing/marketing_wizard.py
index 443fb09ed48..aee302283b2 100644
--- a/addons/marketing/marketing_wizard.py
+++ b/addons/marketing/marketing_wizard.py
@@ -24,15 +24,13 @@ from osv import fields, osv
class marketing_installer(osv.osv_memory):
_name = 'marketing.installer'
_inherit = 'res.config.installer'
-
_columns = {
# Generic modules
- 'marketing_campaign':fields.boolean('Marketing Campaign',
- help="Helps you to manage your marketing campaigns step by step."),
- 'crm_profiling':fields.boolean('Crm Profile',
- help="Helps you to perform segmentation within partners.")
- }
-
+ 'marketing_campaign':fields.boolean('Marketing Campaigns',
+ help="Helps you to manage marketing campaigns and automate actions and communication steps."),
+ 'crm_profiling':fields.boolean('Profiling Tools',
+ help="Helps you to perform segmentation within partners and design questionaires.")
+ }
marketing_installer()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/marketing_campaign/__openerp__.py b/addons/marketing_campaign/__openerp__.py
index aca6c2f6d28..992731c1332 100755
--- a/addons/marketing_campaign/__openerp__.py
+++ b/addons/marketing_campaign/__openerp__.py
@@ -24,10 +24,9 @@
"name" : "",
"version" : "1.1",
"depends" : ["marketing",
- "crm",
+ "crm",
"document",
- "poweremail" # need to get this module form the branch
- # lp:poweremail
+ "email_template"
],
"author" : "Tiny",
"category": 'Generic Modules/Marketing',
@@ -40,7 +39,6 @@
'marketing_campaign_data.xml',
'marketing_campaign_workflow.xml',
'report/campaign_analysis_view.xml',
- 'marketing_campaign_demo.xml'
],
'demo_xml': [
'marketing_campaign_demo.xml',
diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py
index 398e0e805be..3f29e03c968 100755
--- a/addons/marketing_campaign/marketing_campaign.py
+++ b/addons/marketing_campaign/marketing_campaign.py
@@ -129,9 +129,7 @@ class marketing_campaign_segment(osv.osv): #{{{
curr_date = time.strftime('%Y-%m-%d %H:%M:%S')
vals = {'state': 'running'}
if not segment.date_run:
- vals['date_run'] = segment.campaign_id.date_run and \
- segment.campaign_id.date_run or \
- time.strftime('%Y-%m-%d %H:%M:%S')
+ vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
if not segment.sync_last_date:
vals['sync_last_date']=curr_date
if not segment.date_done:
@@ -142,7 +140,7 @@ class marketing_campaign_segment(osv.osv): #{{{
def state_done_set(self, cr, uid, ids, *args):
date_done = self.browse(cr, uid, ids[0]).date_done
- if (date_done > time.strftime('%Y-%m-%d')):
+ if (date_done > time.strftime('%Y-%m-%d %H:%M:%S')):
raise osv.except_osv("Error", "Segment cannot be closed before end date")
wi_ids = self.pool.get("marketing.campaign.workitem").search(cr, uid,
@@ -186,7 +184,7 @@ class marketing_campaign_segment(osv.osv): #{{{
}
self.pool.get('marketing.campaign.workitem').create(
cr, uid, wi_vals)
- self.write(cr, uid, segment.id, {'sync_last_date':action_date})
+ self.write(cr, uid, segment.id, {'sync_last_date':action_date})
return True
marketing_campaign_segment()#}}}
@@ -196,7 +194,7 @@ class marketing_campaign_activity(osv.osv): #{{{
_description = "Campaign Activity"
_columns = {
- 'name': fields.char('Name', size=64, required=True),
+ 'name': fields.char('Name', size=128, required=True),
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
required = True, ondelete='cascade'),
'object_id': fields.related('campaign_id','object_id',
@@ -212,7 +210,7 @@ class marketing_campaign_activity(osv.osv): #{{{
('action', 'Action'),
('subcampaign', 'Sub-Campaign')],
'Type', required=True),
- 'email_template_id': fields.many2one('poweremail.templates','Email Template'),
+ 'email_template_id': fields.many2one('email.template','Email Template'),
'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
'report_directory_id': fields.many2one('document.directory','Directory',
help="Folder is used to store the generated reports"),
@@ -254,8 +252,9 @@ class marketing_campaign_activity(osv.osv): #{{{
def process(self, cr, uid, act_id, wi_id, context={}):
activity = self.browse(cr, uid, act_id)
- workitem_obj = self.pool.get('marketing.campaign.workitem')
+ workitem_obj = self.pool.get('marketing.campaign.workitem')
workitem = workitem_obj.browse(cr, uid, wi_id)
+
if activity.type == 'paper' :
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {})
@@ -278,12 +277,12 @@ class marketing_campaign_activity(osv.osv): #{{{
if not workitem.partner_id.email:
return {'error_msg' : "There is no email defined for the partner"}
vals = {
- 'pem_from': tools.ustr(accounts.name) + "<" + tools.ustr(accounts.email_id) + ">",
- 'pem_to': workitem.partner_id.email,
- 'pem_subject': template.def_subject,
- 'pem_body_text': template.def_body_text,
- 'pem_body_html': template.def_body_html,
- 'pem_account_id':accounts.id,
+ 'email_from': tools.ustr(accounts.name) + "<" + tools.ustr(accounts.email_id) + ">",
+ 'email_to': workitem.partner_id.email,
+ 'subject': template.def_subject,
+ 'body_text': template.def_body_text,
+ 'body_html': template.def_body_html,
+ 'account_id':accounts.id,
'state':'na',
'mail_type':'multipart/alternative' #Options:'multipart/mixed','multipart/alternative','text/plain','text/html'
}
@@ -294,12 +293,11 @@ class marketing_campaign_activity(osv.osv): #{{{
# vals['pem_body_html'] = tools.ustr(vals['pem_body_html'] or '') + signature
#Create partly the mail and later update attachments
- mail_id = self.pool.get('poweremail.mailbox').create(cr, uid, vals, context)
+ mail_id = self.pool.get('email_template.mailbox').create(cr, uid, vals, context)
elif activity.type == 'action' :
server_obj = self.pool.get('ir.actions.server')
server_obj.run(cr, uid, [activity.server_action_id.id], context)
#???
-
return True
marketing_campaign_activity()#}}}
@@ -410,13 +408,13 @@ class marketing_campaign_workitem(osv.osv): #{{{
marketing_campaign_workitem() #}}}
-class poweremail_templates(osv.osv):
- _inherit = "poweremail.templates"
+class email_template(osv.osv):
+ _inherit = "email.template"
_defaults = {
'object_name': lambda obj, cr, uid, context: context.get('object_id',False),
}
-poweremail_templates()
+email_template()
class report_xml(osv.osv):
diff --git a/addons/marketing_campaign/marketing_campaign_demo.xml b/addons/marketing_campaign/marketing_campaign_demo.xml
index 9c2211903c5..7296ebf9c50 100644
--- a/addons/marketing_campaign/marketing_campaign_demo.xml
+++ b/addons/marketing_campaign/marketing_campaign_demo.xml
@@ -21,8 +21,9 @@
<field eval="&quot;&quot;&quot;ressource&quot;&quot;&quot;" name="type"/>
<field name="ressource_type_id" ref="model_marketing_campaign"/>
</record>
-<!-- Power email tempalte -->
- <record id="poweremail_templates_foropenerpondemandfreetrial0" model="poweremail.templates">
+
+ <!-- Email tempalte -->
+ <record id="email_template_1" model="email.template">
<field name="def_subject">Thanks for showing interest in OpenERP</field>
<field name="def_to">info@tinyerp.com</field>
<field eval="[(6,0,[])]" name="allowed_groups"/>
@@ -32,17 +33,163 @@
<field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
<field name="object_name" ref="crm.model_crm_lead"/>
<field eval="0" name="use_sign"/>
- <field name="def_body_text">Hello,
-Thanks for generous interest you have shown in the open ERP.
-Regards,
-OpenERP Team,</field>
+ <field name="def_body_text">Hello,Thanks for generous interest you have shown in the open ERP.Regards,OpenERP Team,</field>
<field name="template_language">mako</field>
<field eval="0" name="send_on_create"/>
<field name="name">For OpenERP OnDemand Free Trial 2010</field>
<field name="model_int_name">crm.lead</field>
<field eval="0" name="send_on_write"/>
</record>
-<!-- Report -->
+ <record id="email_template_2" model="email.template">
+ <field name="def_subject">Propose to subscribe to the Open ERP Discovery Day on May 2010</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello,We have very good offer that might suit you.
+ We propose you to subscribe to the Open ERP Discovery Day on May 2010.
+ If any further information required kindly revert back.
+ We really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For Open ERP Discovery Day on May 2010</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_3" model="email.template">
+ <field name="def_subject">Thanks for subscribing to the Open ERP Discovery Day</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello,Thanks for showing intrest and for subscribing to the Open ERP Discovery Day.
+ If any further information required kindly revert back.
+ I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For Open ERP Discovery Day</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_4" model="email.template">
+ <field name="def_subject">Thanks for buying the Open ERP book</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello,Thanks for showing intrest and buying the Open ERP book.
+ If any further information required kindly revert back.
+ I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For Open ERP book</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_5" model="email.template">
+ <field name="def_subject">Propose a free technical training to Gold partners</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello, We have very good offer that might suit you.
+ For our gold partners,We are arranging free technical training on june,2010.
+ If any further information required kindly revert back.
+ I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For technical training to Gold partners</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_6" model="email.template">
+ <field name="def_subject">Propose paid training to Silver partners</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello, We have very good offer that might suit you.
+ For our silver partners,We are paid technical training on june,2010.
+ If any further information required kindly revert back.
+ I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For training to Silver partners</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_7" model="email.template">
+ <field name="def_subject">Propose gold partnership to silver partners</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello, We have very good offer that might suit you.
+ For our silver partners,We are offering Gold partnership.
+ If any further information required kindly revert back.
+ I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For gold partnership to silver partners</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+
+ <record id="email_template_8" model="email.template">
+ <field name="def_subject">Thanks for subscribing to technical training</field>
+ <field name="def_to">info@tinyerp.com</field>
+ <field eval="[(6,0,[])]" name="allowed_groups"/>
+ <field eval="0" name="auto_email"/>
+ <field model="ir.actions.act_window" name="ref_ir_act_window" search="[('name', '=', u'For OpenERP OnDemand Free Trial 2010 Mail Form')]"/>
+ <field eval="[(6,0,[])]" name="table_required_fields"/>
+ <field model="ir.values" name="ref_ir_value" search="[('name', '=', u'Send Mail (For OpenERP OnDemand Free Trial 2010)')]"/>
+ <field name="object_name" ref="crm.model_crm_lead"/>
+ <field eval="0" name="use_sign"/>
+ <field name="def_body_text">Hello, Thanks for showing intrest and for subscribing to technical training.If any further information required kindly revert back.I really appreciate your co-operation on this.
+ Regards,OpenERP Team,</field>
+ <field name="template_language">mako</field>
+ <field eval="0" name="send_on_create"/>
+ <field name="name">For subscribing to technical training</field>
+ <field name="model_int_name">crm.lead</field>
+ <field eval="0" name="send_on_write"/>
+ </record>
+ <!-- Report -->
+
<record id="mc_crm_lead_demo_report" model="ir.actions.report.xml">
<field name="name">Marketing campaign demo report</field>
<field name="type">ir.actions.report.xml</field>
@@ -51,12 +198,15 @@ OpenERP Team,</field>
<field name="report_rml">marketing_campaign/report/crm_lead_mc_demo_report.rml</field>
<field name="report_type">pdf</field>
</record>
-<!-- Campaign -->
+
+ <!-- Campaign -->
<record id="marketing_campaign_openerpondemandfreetrial0" model="marketing.campaign">
<field name="name">OpenERP OnDemand Free Trial 2010</field>
<field name="object_id" ref="crm.model_crm_lead"/>
</record>
-<!-- Activity -->
+
+ <!-- Activity -->
+
<record id="marketing_campaign_activity_0" model="marketing.campaign.activity">
<field name="name">Propose a 1 month free trial for an OnDemand offer</field>
<field name="server_action_id" ref="base.action_start_configurator"/>
@@ -70,13 +220,112 @@ OpenERP Team,</field>
<field name="name">Thanks for showing interest</field>
<field name="server_action_id" ref="base.action_start_configurator"/>
<field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_1"/>
</record>
-<!-- Tranisition -->
+
+ <record id="marketing_campaign_activity_2" model="marketing.campaign.activity">
+ <field name="name">Propose to subscribe to the Open ERP Discovery Day on May 2010</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_2"/>
+ </record>
+
+ <record id="marketing_campaign_activity_3" model="marketing.campaign.activity">
+ <field name="name">Thanks for subscribing to the Open ERP Discovery Day</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_3"/>
+ </record>
+ <record id="marketing_campaign_activity_4" model="marketing.campaign.activity">
+ <field name="name">Propose to buy the Open ERP Book</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="report_directory_id" ref="document_directory_campaign1"/>
+ <field name="type">paper</field>
+ <field name="report_id" ref="mc_crm_lead_demo_report"/>
+ </record>
+
+ <record id="marketing_campaign_activity_5" model="marketing.campaign.activity">
+ <field name="name">Thanks for buying the Open ERP book</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_4"/>
+ </record>
+ <record id="marketing_campaign_activity_6" model="marketing.campaign.activity">
+ <field name="name">Propose a free technical training to Gold partners</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_5"/>
+ </record>
+ <record id="marketing_campaign_activity_7" model="marketing.campaign.activity">
+ <field name="name">Propose paid training to Silver partners</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_6"/>
+ </record>
+
+ <record id="marketing_campaign_activity_8" model="marketing.campaign.activity">
+ <field name="name">Propose gold partnership to silver partners</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_7"/>
+ </record>
+
+ <record id="marketing_campaign_activity_9" model="marketing.campaign.activity">
+ <field name="name">Thanks for subscribing to technical training</field>
+ <field name="server_action_id" ref="base.action_start_configurator"/>
+ <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
+ <field name="email_template_id" ref="email_template_8"/>
+ </record>
+
+ <!-- Tranisition -->
<record id="marketing_campaign_transition_0" model="marketing.campaign.transition">
<field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_0"/>
<field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_1"/>
</record>
-<!-- Segment -->
+
+ <record id="marketing_campaign_transition_1" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_0"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_2"/>
+ </record>
+ <record id="marketing_campaign_transition_2" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_2"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_3"/>
+ </record>
+ <record id="marketing_campaign_transition_3" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_2"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_4"/>
+ </record>
+ <record id="marketing_campaign_transition_4" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_4"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_5"/>
+ </record>
+ <record id="marketing_campaign_transition_5" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_4"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_6"/>
+ </record>
+ <record id="marketing_campaign_transition_6" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_4"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_7"/>
+ </record>
+ <record id="marketing_campaign_transition_7" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_6"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_9"/>
+ </record>
+ <record id="marketing_campaign_transition_8" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_7"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_8"/>
+ </record>
+ <record id="marketing_campaign_transition_9" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_7"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_9"/>
+ </record>
+ <record id="marketing_campaign_transition_10" model="marketing.campaign.transition">
+ <field model="marketing.campaign.activity" name="activity_from_id" ref = "marketing_campaign_activity_9"/>
+ <field model="marketing.campaign.activity" name="activity_to_id" ref = "marketing_campaign_activity_1"/>
+ </record>
+
+ <!-- Segment -->
<record id="marketing_campaign_segment_bosslistusassociationslist0" model="marketing.campaign.segment">
<field eval="time.strftime('%Y-%m-%d %H:%M:%S')" name="date_run"/>
<field name="name">BossList US Associations List-0/90</field>
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 15ed872391f..bcda66e8679 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -296,9 +296,9 @@
<field name="company_id" groups="base.group_multi_company"/>
</group>
<newline/>
- <group expand="1" string="Group By" colspan="4" col="8" groups="base.group_extended">
- <filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product_id'}"/>
- <filter string="Routing" icon="terp-mrp" domain="[]" context="{'group_by':'routing_id'}"/>
+ <group expand="0" string="Group By" colspan="4" col="8" groups="base.group_extended">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="Routing" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'routing_id'}"/>
</group>
</search>
</field>
@@ -655,21 +655,21 @@
<field name="arch" type="xml">
<search string="Search Production">
<group col='9' colspan='4'>
- <filter icon="terp-mrp" string="Draft"
+ <filter icon="terp-document-new" string="Draft"
domain="[('state','=','draft')]"
help="Non confirmed manufacturing orders"/>
- <filter icon="terp-mrp" string="Current" name="Current"
+ <filter icon="terp-check" string="Current" name="Current"
default="1"
domain="[('state','in',('confirmed','ready','exception'))]"
help="Manufacturing Orders which are waiting for raw materials"/>
- <filter icon="terp-mrp" string="Ready"
+ <filter icon="terp-camera_test" string="Ready"
domain="[('state','=','ready')]"
help="Manufacturing Orders which are ready to produce" />
- <filter icon="terp-mrp" string="In Production"
+ <filter icon="terp-check" string="In Production"
domain="[('state','=','in_production')]"
help="Manufacturing Orders which are in production" />
<separator orientation="vertical"/>
- <filter icon="terp-mrp" string="Late"
+ <filter icon="terp-gnome-cpu-frequency-applet+" string="Late"
domain="['&amp;', ('date_planned::date','&lt;', current_date), ('state', 'in', ('draft', 'confirmed', 'ready'))]"
help="Production started late" />
<separator orientation="vertical"/>
@@ -679,12 +679,12 @@
<field name="origin"/>
</group>
<newline/>
- <group expand="1" string="Group By" colspan="10" col="8">
- <filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product_id'}"/>
- <filter string="State" icon="terp-mrp" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Routing" icon="terp-mrp" domain="[]" context="{'group_by':'routing_id'}" groups="base.group_extended"/>
+ <group expand="0" string="Group By" colspan="10" col="8">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Routing" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'routing_id'}" groups="base.group_extended"/>
<separator orientation="vertical"/>
- <filter string="Date" icon="terp-mrp" domain="[]" context="{'group_by':'date_planned'}"/>
+ <filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_planned'}"/>
</group>
</search>
</field>
diff --git a/addons/mrp/report/mrp_production_order_view.xml b/addons/mrp/report/mrp_production_order_view.xml
index 5663ef93210..55957619e31 100644
--- a/addons/mrp/report/mrp_production_order_view.xml
+++ b/addons/mrp/report/mrp_production_order_view.xml
@@ -12,19 +12,18 @@
<field name="arch" type="xml">
<tree string="Production">
<field name="date_planned"/>
- <field name="origin"/>
- <field name="bom_id" />
- <field name="product_id"/>
+ <field name="bom_id" invisible="1"/>
+ <field name="product_id" invisible="1"/>
<field name="product_qty" sum='Product Qty'/>
<field name="nbr" string="#Production Orders" sum='#Production Orders'/>
- <field name="state"/>
- <field name="routing_id" invisible="1"/>
+ <field name="state" invisible="1"/>
<field name="picking_id" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="year" invisible="1" />
<field name="month" invisible="1"/>
<field name="location_src_id" invisible="1"/>
<field name="location_dest_id" invisible="1"/>
+ <field name="company_id" groups="base.group_multi_company" invisible="1"/>
</tree>
</field>
</record>
@@ -48,50 +47,57 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="6">
- <filter string="This Year" icon="terp-mrp" domain="[('year','=',time.localtime()[0])]" default="1" />
- <filter string="This Month" icon="terp-mrp" domain="[('month','=',time.strftime('%%m'))]" default="1"/>
- <separator orientation="vertical"/>
- <filter string="Current" icon="terp-mrp" domain="[('state','in',('open','draft'))]"/>
- <separator orientation="vertical"/>
- <field name="origin"/>
- <field name="date_planned"/>
+ <filter icon="terp-go-year" string=" 365 Days "
+ domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')),('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
+ help="Production performed in last 365 Days"/>
+ <filter icon="terp-go-month" string=" 30 Days "
+ name="month"
+ domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
+ help="Production performed in last 30 days"/>
+ <filter icon="terp-go-week"
+ string=" 7 Days "
+ separator="1"
+ domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
+ help="Production during last 7 days"/>
+ <separator orientation="vertical"/>
+ <filter string="Current" icon="terp-check" domain="[('state','in',('open','draft'))]"/>
+ <filter icon="terp-check" string="In Production" domain="[('state','=','in_production')]"/>
+ <filter icon="terp-dialog-close" string="Done" domain="[('state','=','done')]"/>
+ <separator orientation="vertical"/>
+ <field name="location_src_id" />
+ <field name="location_dest_id" />
</group>
<newline/>
- <group expand="1" string="Group By...">
- <filter string="Source Location" icon="terp-mrp" context="{'group_by':'location_src_id'}"/>
- <filter string="Destination Location" icon="terp-mrp" context="{'group_by':'location_dest_id'}"/>
- <filter string="Picking" icon="terp-mrp" context="{'group_by':'picking_id'}"/>
- <separator orientation="vertical"/>
- <filter string="Routing" icon="terp-mrp" context="{'group_by':'routing_id'}"/>
- <filter string="Product" name="Product" icon="terp-mrp" context="{'group_by':'product_id'}" />
- <filter string="State" icon="terp-mrp" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By...">
+ <filter string="Raw Material Location" icon="terp-gtk-jump-to-rtl" context="{'group_by':'location_src_id'}"/>
+ <filter string="Finished Products Location" icon="terp-gtk-jump-to-ltr" context="{'group_by':'location_dest_id'}"/>
<separator orientation="vertical"/>
+ <filter string="Product" name="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}" />
<filter string="BOM" icon="terp-mrp" context="{'group_by':'bom_id'}"/>
- <filter string="Month" icon="terp-mrp" context="{'group_by':'month'}"/>
- <filter string="Year" icon="terp-mrp" context="{'group_by':'year'}"/>
+ <separator orientation="vertical"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Company" icon="terp-go-home" context="{'group_by':'company_id'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Day" icon="terp-go-month" context="{'group_by':'day'}"/>
+ <filter string="Month" name="month" icon="terp-go-month" context="{'group_by':'month'}"/>
+ <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
- <filter icon="terp-mrp" string="Draft" domain="[('state','=','draft')]"/>
- <filter icon="terp-mrp" string="Picking Exception" domain="[('state','=','picking_except')]"/>
- <separator orientation="vertical"/>
- <filter icon="terp-mrp" string="Waiting Goods" domain="[('state','=','confirmed')]"/>
- <filter icon="terp-mrp" string="Ready to Produce" domain="[('state','=','ready')]"/>
- <separator orientation="vertical"/>
- <filter icon="terp-mrp" string="In Production" domain="[('state','=','in_production')]"/>
- <filter icon="terp-mrp" string="Done" domain="[('state','=','done')]"/>
- <filter icon="terp-mrp" string="Cancelled" domain="[('state','=','cancel')]"/>
- <newline/>
- <filter icon="terp-mrp" string="Not urgent" domain="[('priority','=','0')]"/>
- <filter icon="terp-mrp" string="Normal" domain="[('priority','=','1')]"/>
- <separator orientation="vertical"/>
- <filter icon="terp-mrp" string="Urgent" domain="[('priority','=','2')]"/>
- <filter icon="terp-mrp" string="Very Urgent" domain="[('priority','=','3')]"/>
+ <filter icon="terp-emblem-important" string="Picking Exception" domain="[('state','=','picking_except')]"/>
+ <filter icon="terp-gtk-media-pause" string="Waiting Goods" domain="[('state','=','confirmed')]"/>
+ <filter icon="terp-camera_test" string="Ready to Produce" domain="[('state','=','ready')]"/>
<separator orientation="vertical"/>
+ <field name="priority"/>
+ <separator orientation="vertical"/>
+ <field name="company_id" groups="base.group_multi_company"/>
+ <newline/>
<field name="date_start"/>
- <field name="date_finnished"/>
- </group>
+ <field name="date_planned"/>
+ <field name="date_finnished"/>
+ </group>
</search>
</field>
</record>
@@ -102,7 +108,7 @@
<field name="view_mode">tree,graph</field>
<field name="view_id" ref="view_report_mrp_production_order_tree"/>
<field name="search_view_id" ref="view_report_mrp_production_order_filter"/>
- <field name="context">{'search_default_Product': 1}</field>
+ <field name="context">{'search_default_Product': 1,'search_default_month':1,'group_by_no_leaf':1,'group_by':[]}</field>
</record>
diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml
index 37e90a995b4..a5c6564644e 100644
--- a/addons/mrp_operations/mrp_operations_view.xml
+++ b/addons/mrp_operations/mrp_operations_view.xml
@@ -96,10 +96,10 @@
<field name="production_id"/>
</group>
<newline/>
- <group expand="1" string="Group By" colspan="10" col="8" groups="base.group_extended">
- <filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product'}"/>
- <filter string="State" icon="terp-mrp" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Date" icon="terp-mrp" domain="[]" context="{'group_by':'date_planned'}"/>
+ <group expand="0" string="Group By" colspan="10" col="8" groups="base.group_extended">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_planned'}"/>
</group>
</search>
</field>
diff --git a/addons/mrp_procurement/mrp_procurement_view.xml b/addons/mrp_procurement/mrp_procurement_view.xml
index 1defa214754..7345dc94f93 100644
--- a/addons/mrp_procurement/mrp_procurement_view.xml
+++ b/addons/mrp_procurement/mrp_procurement_view.xml
@@ -86,12 +86,12 @@
<field name="arch" type="xml">
<search string="Search Procurement">
<group col='10' colspan='4'>
- <filter icon="terp-mrp" string="Current" domain="[('state','in',('draft','confirmed'))]" name="current" help="Procurement Orders in draft or open state."/>
- <filter icon="terp-mrp" string="Exceptions" domain="[('state','=','exception')]" help="Procurement Orders with exceptions"/>
- <filter icon="terp-mrp" string="Late"
+ <filter icon="terp-check" string="Current" domain="[('state','in',('draft','confirmed'))]" name="current" help="Procurement Orders in draft or open state."/>
+ <filter icon="terp-emblem-important" string="Exceptions" domain="[('state','=','exception')]" help="Procurement Orders with exceptions"/>
+ <filter icon="terp-gnome-cpu-frequency-applet+" string="Late"
domain="['&amp;', ('date_planned::date','&lt;', current_date), ('state', 'in', ('draft', 'confirmed'))]"
help="Procurement started late" />
- <filter icon="terp-mrp" string="To Fix" domain="[('state', '=', 'exception'),('message','=','')]" help="Procurement Orders with exceptions and without message"/>
+ <filter icon="terp-gtk-go-back-rtl" string="To Fix" domain="[('state', '=', 'exception'),('message','=','')]" help="Procurement Orders with exceptions and without message"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="origin"/>
@@ -100,11 +100,11 @@
<field name="state" />
</group>
<newline/>
- <group expand="1" string="Group By" colspan="4" col="8" groups="base.group_extended">
- <filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product_id'}"/>
- <filter string="Reason" icon="terp-mrp" domain="[]" context="{'group_by':'name'}"/>
- <filter string="Scheduled Date" icon="terp-mrp" domain="[]" context="{'group_by':'date_planned'}"/>
- <filter string="State" icon="terp-mrp" domain="[]" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By" colspan="4" col="8" groups="base.group_extended">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="Reason" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'name'}"/>
+ <filter string="Scheduled Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_planned'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
@@ -191,9 +191,9 @@
<field name="product_id"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="10">
- <filter string="Warehouse" icon="terp-stock" domain="[]" context="{'group_by':'warehouse_id'}"/>
- <filter string="Location" icon="terp-stock" domain="[]" context="{'group_by':'location_id'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="10">
+ <filter string="Warehouse" icon="terp-go-home" domain="[]" context="{'group_by':'warehouse_id'}"/>
+ <filter string="Location" icon="terp-go-home" domain="[]" context="{'group_by':'location_id'}"/>
</group>
</search>
</field>
diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml
index 47e80be3e31..4c655099386 100644
--- a/addons/mrp_repair/mrp_repair_view.xml
+++ b/addons/mrp_repair/mrp_repair_view.xml
@@ -183,10 +183,10 @@
<field name="product_id" />
</group>
<newline/>
- <group expand="1" string="Group By" colspan="10" col="8" groups="base.group_extended">
- <filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product_id'}"/>
- <filter string="State" icon="terp-mrp" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Partner" icon="terp-mrp" domain="[]" context="{'group_by':'partner_id'}"/>
+ <group expand="0" string="Group By..." colspan="10" col="8" groups="base.group_extended">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
</group>
</search>
</field>
diff --git a/addons/point_of_sale/pos_view.xml b/addons/point_of_sale/pos_view.xml
index ef8ae334810..62b15db0234 100644
--- a/addons/point_of_sale/pos_view.xml
+++ b/addons/point_of_sale/pos_view.xml
@@ -153,19 +153,19 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Sales Order">
- <filter icon="terp-sale" string="Quotations" domain="[('state','=','draft')]"/>
- <filter icon="terp-sale" string="Running" domain="[('state','in',('payment','advance'))]"/>
+ <filter icon="terp-document-new" string="Quotations" domain="[('state','=','draft')]"/>
+ <filter icon="terp-check" string="Running" domain="[('state','in',('payment','advance'))]"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="partner_id" select="1"/>
<field name="user_id" select="1" widget="selection"/>
<field name="date_order" select="1" string="Order date" />
<newline/>
- <group expand="1" string="Group By..." colspan="11" col="11" groups="base.group_extended">
- <filter string="Customer" icon="terp-sale" domain="[]" context="{'group_by':'partner_id'}"/>
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Order Date" icon="terp-sale" domain="[]" context="{'group_by':'date_order'}"/>
- <filter string="Salesman" icon="terp-sale" domain="[]" context="{'group_by':'user_id'}"/>
+ <group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
+ <filter string="Customer" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
+ <filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index aa73cdd0e63..11ed4bfba65 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -1,29 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
- <menuitem groups="base.group_extended" id="prod_config_main" name="Product" parent="base.menu_base_config" sequence="50"/>
+ <menuitem groups="base.group_extended" id="prod_config_main" name="Product" parent="base.menu_base_config" sequence="40"/>
+
<record id="product_search_form_view" model="ir.ui.view">
<field name="name">product.search.form</field>
<field name="model">product.product</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Product">
- <filter string="Services" icon="terp-stock" domain="[('type','=','service')]"/>
- <filter string="Stockable" icon="terp-stock" domain="['|',('type','=','product'),('type','=','consu')]"/>
+ <filter string="Services" icon="terp-accessories-archiver" domain="[('type','=','service')]"/>
+ <filter string="Stockable" icon="terp-accessories-archiver" domain="['|',('type','=','product'),('type','=','consu')]"/>
<separator orientation="vertical"/>
- <filter string="Can be sold" icon="terp-stock" domain="[('sale_ok','=',1)]"/>
- <filter string="Can be Purchased" icon="terp-stock" domain="[('purchase_ok', '=', 1)]" />
+ <filter string="Can be sold" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
+ <filter string="Can be Purchased" icon="terp-accessories-archiver+" domain="[('purchase_ok', '=', 1)]" />
<separator orientation="vertical"/>
<field name="default_code"/>
<field name="name"/>
<field name="categ_id" widget="selection" operator="child_of"/>
<newline/>
- <group expand='1' string='Group by...' groups="base.group_extended">
- <filter string='Category' icon="terp-stock" domain="[]" context="{'group_by' : 'categ_id'}" />
+ <group expand='0' string='Group by...' groups="base.group_extended">
+ <filter string='Category' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'categ_id'}" />
<separator orientation="vertical"/>
- <filter string='Default UOM' icon="terp-stock" domain="[]" context="{'group_by' : 'uom_id'}" />
+ <filter string='Default UOM' icon="terp-mrp" domain="[]" context="{'group_by' : 'uom_id'}" />
<separator orientation="vertical"/>
- <filter string='Type' icon="terp-stock" domain="[]" context="{'group_by' : 'type'}" />
+ <filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}" />
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
@@ -260,7 +261,7 @@
<menuitem action="product_category_action_form"
groups="base.group_extended"
id="menu_product_category_action_form"
- parent="prod_config_main" sequence="60"/>
+ parent="prod_config_main" sequence="2"/>
<record id="product_normal_action_tree" model="ir.actions.act_window">
@@ -374,7 +375,7 @@
<field name="view_mode">tree,form</field>
</record>
<menuitem
- action="product_ul_form_action" groups="base.group_extended" id="menu_product_ul_form_action" parent="prod_config_main" sequence="65"/>
+ action="product_ul_form_action" groups="base.group_extended" id="menu_product_ul_form_action" parent="prod_config_main" sequence="3"/>
<record id="product_packaging_tree_view" model="ir.ui.view">
<field name="name">product.packaging.tree.view</field>
diff --git a/addons/profile_accounting/__openerp__.py b/addons/profile_accounting/__openerp__.py
index 4e3e2e10481..9e02bd3e275 100644
--- a/addons/profile_accounting/__openerp__.py
+++ b/addons/profile_accounting/__openerp__.py
@@ -26,7 +26,7 @@
'category': 'Profile',
'description': """Profile for Accounting""",
'author': 'Tiny',
- 'depends': ['account', 'report_analytic', 'board_account', 'account_followup'],
+ 'depends': ['account', 'board_account', 'account_followup'],
'update_xml': ['security/ir.model.access.csv', 'profile_accounting.xml'],
'demo_xml': [],
'installable': True,
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index f668d82bf5c..973194e0e31 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -256,5 +256,15 @@
<field name="project_id" ref="project_project_22"/>
<field name="name">Latest in house tests</field>
</record>
+ <record id="project_message_1" model="project.message">
+ <field name="date">2010-05-27</field>
+ <field name="project_id" ref="project.project_project_23"/>
+ <field name="user_id" ref="base.user_root"/>
+ <field name="description">Follow the procedure of Configuration wizard.
+- Add all required modules
+- Add chat of accounts
+- Create Users</field>
+ <field name="subject">Configuration steps</field>
+ </record>
</data>
</openerp>
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index d7a7ff0e8d4..e979632bab4 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -93,7 +93,7 @@
<field name="type">tree</field>
<field name="priority" eval="5"/>
<field name="arch" type="xml">
- <tree string="Projects">
+ <tree colors="blue:state in ('pending');black:state in ('open','template','close');gray:state in ('cancelled') " string="Projects">
<field name="complete_name" string="Project Name"/>
<field name="user_id" string="Project Manager"/>
<field name="partner_id" string="Partner"/>
@@ -111,22 +111,20 @@
<field name="arch" type="xml">
<search string="Search Project">
<group col='15' colspan='4'>
- <filter icon="terp-project" string="Open" domain="[('state', 'in',('open','draft'))]" help="Open and Draft Projects" default="1"/>
- <filter icon="terp-project" string="Pending" domain="[('state', '=', 'pending')]" help="Pending Projects"/>
+ <filter icon="terp-document-new" string="Draft" domain="[('state', 'in',('draft'))]" help="Draft Projects" default="1"/>
+ <filter icon="terp-check" string="Current" name="Current" domain="[('state', 'in',('open','pending'))]" help="Open and Pending Projects" default="1"/>
<separator orientation="vertical"/>
- <filter icon="terp-project" string="Manager" domain="[('user_id', '=', uid)]" help="Projects in which I am a manager."/>
- <filter icon="terp-project" string="Member" domain="['|',('user_id', '=', uid),('members', '=', uid)]" help="Projects in which I am a member." default="1"/>
- <separator orientation="vertical"/>
- <filter icon="terp-project" string="Templates" domain="[('state','=','template')]" help="Template Projects"/>
+ <filter icon="terp-personal" string="Manager" name="Manager" domain="[('user_id', '=', uid)]" help="Projects in which I am a manager."/>
+ <filter icon="terp-personal-" string="Member" domain="['|',('user_id', '=', uid),('members', '=', uid)]" help="Projects in which I am a member." default="1"/>
<separator orientation="vertical"/>
<field name="name" string="Project Name"/>
<field name="user_id" string="Project Manager" default="1"/>
<field name="partner_id" string="Partner"/>
</group>
<newline />
- <group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
- <filter string="Users" name="Users" icon="terp-project" domain = "[]" context="{'group_by':'user_id'}"/>
- <filter string="Partner" name="Partner" icon="terp-project" domain = "[]" context="{'group_by':'partner_id'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
+ <filter string="Users" name="Users" icon="terp-personal" domain = "[]" context="{'group_by':'user_id'}"/>
+ <filter string="Partner" name="Partner" icon="terp-personal" domain = "[]" context="{'group_by':'partner_id'}"/>
</group>
</search>
</field>
@@ -159,6 +157,7 @@
<field name="domain">[]</field>
<field name="view_id" ref="view_project"/>
<field name="search_view_id" ref="view_project_project_filter"/>
+ <field name="context">{'search_default_Current':1}</field>
</record>
<menuitem action="open_view_project_all" id="menu_open_view_project_all" parent="menu_project_management" sequence="1"/>
@@ -169,8 +168,8 @@
<field name="domain">[('state','=','template')]</field>
<field name="view_id" ref="view_project"/>
</record>
- <menuitem id="menu_template_project_specification" parent="project.menu_definitions" name="Specification" sequence="1"/>
- <menuitem action="open_view_template_project" id="menu_template_project" parent="project.menu_template_project_specification" name="Specification Template"/>
+<!-- <menuitem id="menu_template_project_specification" parent="project.menu_definitions" name="Specification" sequence="1"/>-->
+<!-- <menuitem action="open_view_template_project" id="menu_template_project" parent="project.menu_template_project_specification" name="Specification Template"/>-->
<record id="view_task_work_form" model="ir.ui.view">
<field name="name">project.task.work.form</field>
@@ -213,7 +212,7 @@
<separator string="" colspan="4"/>
<group col="4" colspan="4">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
- <button icon="gtk-refresh" name="compute_hours" string="Update" type="object" default_focus="1"/>
+ <button icon="gtk-apply" name="compute_hours" string="Update" type="object" default_focus="1"/>
</group>
</form>
</field>
@@ -277,7 +276,7 @@
<button name="%(action_config_compute_remaining)d" states="done,cancelled" string="Reactivate" type="action" icon="gtk-convert" context="{'button_reactivate':True}" />
<button name="do_pending" states="open" string="Pending" type="object" icon="gtk-media-pause"/>
<button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open" string="Delegate" type="action" icon="gtk-sort-descending"/>
- <button name="do_close" states="pending,open" string="Done" type="object" icon="gtk-jump-to"/>
+ <button name="do_close" states="pending,open" string="Done" type="object" icon="gtk-apply"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/>
</group>
</page>
@@ -332,8 +331,8 @@
<field name="type">tree</field>
<field eval="2" name="priority"/>
<field name="arch" type="xml">
- <tree colors="grey:state in ('cancelled','done');blue:remaining_hours&lt;0;red:bool(date_deadline) and (date_deadline&lt;current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks">
- <field name="sequence" invisible="1"/>
+ <tree colors="grey:state in ('cancelled','done');blue:remaining_hours&lt;0 and state in ('pending');red:bool(date_deadline) and (date_deadline&lt;current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks">
+ <field name="sequence" />
<field name="name"/>
<field name="project_id" icon="gtk-indent" domain="['|',('user_id','=',uid),('members','=',uid)]"/>
<field name="user_id"/>
@@ -355,8 +354,8 @@
<field name="progress" widget="progressbar" invisible="context.get('set_visible',False)"/>
<field name="state" invisible="context.get('set_visible',False)"/>
<button name="do_open" states="pending,draft,done,cancel" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state" invisible="context.get('set_visible',False)"/>
- <button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-execute" help="For changing to delegate state"/>
- <button name="do_close" states="draft,pending,open" string="Done" type="object" icon="gtk-jump-to" help="For changing to done state"/>
+ <button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-sort-descending" help="For changing to delegate state"/>
+ <button name="do_close" states="draft,pending,open" string="Done" type="object" icon="gtk-apply" help="For changing to done state"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
</tree>
</field>
@@ -409,30 +408,30 @@
<field name="arch" type="xml">
<search string="Task Edition">
<group col="20" colspan="4">
- <filter name="current" string="Current" domain="[('state','in',('open','draft'))]" help="Draft, Open and Pending Tasks" icon="terp-project" default="1"/>
- <filter string="In Progress" domain="[('state','=','open')]" help="Open Tasks" icon="terp-project"/>
- <filter string="Pending" domain="[('state','=','pending')]" context="{'show_delegated':False}" help="Pending Tasks" icon="terp-project"/>
+ <filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft, Open and Pending Tasks" icon="terp-check" default="1"/>
+ <filter string="In Progress" domain="[('state','=','open')]" help="Open Tasks" icon="terp-camera_test"/>
+ <filter string="Pending" domain="[('state','=','pending')]" context="{'show_delegated':False}" help="Pending Tasks" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
- <filter string="Deadlines" domain="[('date_deadline','&lt;&gt;',False)]" help="Show only tasks having a deadline" icon="terp-project"/>
+ <filter string="Deadlines" domain="[('date_deadline','&lt;&gt;',False)]" help="Show only tasks having a deadline" icon="terp-emblem-important"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="project_id" select="1" widget="selection">
- <filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-project"/>
+ <filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-folder-blue"/>
</field>
<field name="user_id" select="1" widget="selection">
<filter domain="[('user_id','=',False)]" help="Unassigned Tasks" icon="gtk-execute" separator="1"/>
</field>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20">
- <filter string="Users" name="group_user_id" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
- <filter string="Project" name="group_project_id" icon="terp-project" domain="[]" context="{'group_by':'project_id'}" default = "1"/>
- <filter string="Stage" name="group_stage_id" icon="terp-project" domain="[]" context="{'group_by':'type'}"/>
- <filter string="State" name="group_state" icon="terp-project" domain="[]" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20">
+ <filter string="Users" name="group_user_id" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+ <filter string="Project" name="group_project_id" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}" default = "1"/>
+ <filter string="Stage" name="group_stage_id" icon="terp-stage" domain="[]" context="{'group_by':'type'}"/>
+ <filter string="State" name="group_state" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
- <filter string="Deadline" icon="terp-project" domain="[]" context="{'group_by':'date_deadline'}"/>
- <filter string="Start Date" icon="terp-project" domain="[]" context="{'group_by':'date_start'}"/>
- <filter string="End Date" icon="terp-project" domain="[]" context="{'group_by':'date_end'}"/>
+ <filter string="Deadline" icon="terp-gnome-cpu-frequency-applet+" domain="[]" context="{'group_by':'date_deadline'}"/>
+ <filter string="Start Date" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
+ <filter string="End Date" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'date_end'}"/>
</group>
</search>
</field>
@@ -591,10 +590,10 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Messages">
+ <field name="date" select="1"/>
<field name="subject" select="1"/>
<field name="project_id" select="1"/>
<field name="user_id" select="1"/>
- <field name="date" select="1"/>
</tree>
</field>
</record>
@@ -606,8 +605,8 @@
<field name="arch" type="xml">
<search string="Messages">
<group col="20" colspan="4">
- <filter domain="[('date','&gt;=',time.strftime('%%Y-%%m-01'))]" icon="terp-project" string="This Month" />
- <filter domain="[('date', '=', time.strftime('%%Y-%%m-%%d'))]" icon="terp-project" string="Today" />
+ <filter domain="[('date','&gt;=',time.strftime('%%Y-%%m-01'))]" icon="terp-go-month" string="This Month" />
+ <filter domain="[('date', '=', time.strftime('%%Y-%%m-%%d'))]" icon="terp-go-today" string="Today" />
<separator orientation="vertical"/>
<field name="subject"/>
<field name="project_id" select="1" widget="selection"/>
@@ -615,10 +614,10 @@
</field>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20">
- <filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
- <filter string="User" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
- <filter string="Date" icon="terp-project" domain="[]" context="{'group_by':'date'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20">
+ <filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
+ <filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+ <filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
</group>
</search>
</field>
diff --git a/addons/project/report/project_report.py b/addons/project/report/project_report.py
index 7984441b460..1cd452d736e 100644
--- a/addons/project/report/project_report.py
+++ b/addons/project/report/project_report.py
@@ -42,11 +42,13 @@ class report_project_task_user(osv.osv):
'hours_effective': fields.float('Effective Hours', readonly=True),
'hours_delay': fields.float('Avg. Plan.-Eff.', readonly=True),
'remaining_hours': fields.float('Remaining Hours', readonly=True),
+ 'progress': fields.float('Progress', readonly=True),
'total_hours': fields.float('Total Hours', readonly=True),
'closing_days': fields.float('Days to Close', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Days to close the task"),
'opening_days': fields.float('Days to Open', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Days to Open the task"),
+ 'delay_endings_days': fields.float('Overpass Delay', digits=(16,2), readonly=True, group_operator="avg"),
'nbr': fields.integer('# of tasks', readonly=True),
'priority' : fields.selection([('4','Very Low'),
('3','Low'),
@@ -63,7 +65,7 @@ class report_project_task_user(osv.osv):
('cancelled', 'Cancelled'),
('done', 'Done')],
'State', readonly=True),
- 'company_id': fields.many2one('res.company', 'Company',readonly=True),
+ 'company_id': fields.many2one('res.company', 'Company',readonly=True, groups="base.group_multi_company"),
'partner_id': fields.many2one('res.partner', 'Partner',readonly=True),
'type': fields.many2one('project.task.type', 'Stage',readonly=True),
@@ -84,6 +86,7 @@ class report_project_task_user(osv.osv):
to_date(to_char(t.date_deadline, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_deadline,
sum(cast(to_char(date_trunc('day',t.date_end) - date_trunc('day',t.date_start),'DD') as int)) as no_of_days,
t.user_id,
+ sum(progress) as progress,
t.project_id,
t.state,
t.priority,
@@ -97,6 +100,7 @@ class report_project_task_user(osv.osv):
sum(planned_hours) as hours_planned,
avg(extract('epoch' from (t.date_end-t.create_date)))/(3600*24) as closing_days,
avg(extract('epoch' from (t.date_start-t.create_date)))/(3600*24) as opening_days,
+ avg(extract('epoch' from (t.date_deadline-t.date_end)))/(3600*24) as delay_endings_days,
sum(w.hours) as hours_effective,
((sum(planned_hours)-sum(w.hours))/count(distinct t.id))::decimal(16,2) as hours_delay
from project_task t
diff --git a/addons/project/report/project_report_view.xml b/addons/project/report/project_report_view.xml
index f40fc218a9e..26488eae254 100644
--- a/addons/project/report/project_report_view.xml
+++ b/addons/project/report/project_report_view.xml
@@ -12,7 +12,7 @@
<field name="name" invisible="1"/>
<field name="project_id" invisible="1"/>
<field name="user_id" invisible="1"/>
- <field name="done_by"/>
+ <field name="done_by" invisible="1"/>
<field name="date_deadline" invisible="1"/>
<field name="state" invisible="1"/>
<field name="date_start" invisible="1"/>
@@ -31,7 +31,9 @@
<field name="hours_effective" sum='Effective Hours'/>
<field name="hours_delay" sum='Avg. Plan.-Eff.'/>
<field name="opening_days" sum='Days to Open'/>
+ <field name="delay_endings_days" sum='OverPass delay'/>
<field name="closing_days" sum='Days to Close'/>
+ <field name="progress" sum='Progress' widget='progressbar'/>
</tree>
</field>
</record>
@@ -55,71 +57,71 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Tasks Analysis">
- <group>
- <filter icon="gtk-media-rewind" string=" 365 Days "
+ <group colspan="10" col="12">
+ <filter icon="terp-go-year" string=" 365 Days "
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')),('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 365 Days"/>
- <filter icon="gtk-media-rewind" string=" 30 Days "
+ <filter icon="terp-go-month" string=" 30 Days "
name="month"
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 30 days"/>
- <filter icon="gtk-media-rewind"
+ <filter icon="terp-go-week"
string=" 7 Days "
separator="1"
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Tasks during last 7 days"/>
<separator orientation="vertical"/>
<filter string="Draft"
- icon="terp-project"
+ icon="terp-document-new"
domain="[('state','=','draft')]"
help = "Draft tasks"/>
<filter string="Current"
- icon="terp-project"
+ icon="terp-check"
domain="[('state', '=' ,'open')]"
help = "In progress tasks"/>
<filter string="Pending"
- icon="terp-project"
+ icon="terp-gtk-media-pause"
domain="[('state','=','pending')]"
help = "Pending tasks"/>
<filter string="Done"
- icon="terp-project"
+ icon="terp-dialog-close"
name="done"
domain="[('state','=','done')]"/>
<separator orientation="vertical"/>
<field name="partner_id" />
<field name="user_id" widget="selection">
- <filter icon="terp-project"
+ <filter icon="terp-personal"
string="My Task"
help = "My tasks"
domain="[('user_id','=',uid)]" />
- <filter icon="terp-project"
+ <filter icon="terp-personal-"
string="Non Assigned Tasks to users"
help="Non Assigned Tasks to users"
domain="[('user_id','=',False)]"/>
</field>
<field name="project_id">
- <filter icon="terp-project"
+ <filter icon="terp-folder-blue"
string="My Projects"
help="My Projects"
domain="[('project_id','=',context.get('project_id', False)]"/>
</field>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="10" col="11">
- <filter string="User" name="User" icon="terp-project" context="{'group_by':'user_id'}" />
- <filter string="Project" icon="terp-project" context="{'group_by':'project_id'}"/>
+ <group expand="0" string="Group By..." colspan="10" col="12">
+ <filter string="User" name="User" icon="terp-personal" context="{'group_by':'user_id'}" />
+ <filter string="Project" icon="terp-folder-blue" context="{'group_by':'project_id'}"/>
<separator orientation="vertical"/>
- <filter string="Partner" icon="terp-project" context="{'group_by':'partner_id'}" />
- <filter string="Task" icon="terp-project" context="{'group_by':'name'}" />
- <filter string="Done By" icon="terp-project" context="{'group_by':'done_by'}" />
+ <filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}" />
+ <filter string="Task" icon="terp-stock_align_left_24" context="{'group_by':'name'}" />
+ <filter string="Done By" icon="terp-personal" context="{'group_by':'done_by'}" />
<separator orientation="vertical"/>
- <filter string="State" icon="terp-project" context="{'group_by':'state'}"/>
- <filter string="Company" icon="terp-project" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
- <filter string="Stage" icon="terp-project" context="{'group_by':'type'}" />
+ <filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
+ <filter string="Company" icon="terp-go-home" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
+ <filter string="Stage" icon="terp-stage" context="{'group_by':'type'}" />
<separator orientation="vertical"/>
- <filter string="Day" icon="terp-project" context="{'group_by':'day'}"/>
- <filter string="Month" icon="terp-project" context="{'group_by':'month'}"/>
- <filter string="Year" icon="terp-project" context="{'group_by':'year'}"/>
+ <filter string="Day" icon="terp-go-month" context="{'group_by':'day'}"/>
+ <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
+ <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." colspan="10" col="12" groups="base.group_extended">
@@ -128,6 +130,7 @@
<separator orientation="vertical"/>
<field name="date_start"/>
<field name="date_deadline"/>
+ <field name="date_end"/>
<separator orientation="vertical"/>
<field name="priority"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py
index 059c19e0f40..d680e533505 100644
--- a/addons/project_gtd/project_gtd.py
+++ b/addons/project_gtd/project_gtd.py
@@ -120,8 +120,8 @@ project_gtd_timebox()
class project_task(osv.osv):
_inherit = "project.task"
_columns = {
- 'timebox_id': fields.many2one('project.gtd.timebox', "Timebox"),
- 'context_id': fields.many2one('project.gtd.context', "Context"),
+ 'timebox_id': fields.many2one('project.gtd.timebox', "Timebox",help="Time-laps during which task has to be treated"),
+ 'context_id': fields.many2one('project.gtd.context', "Context",help="The context place where user has to treat task"),
}
def copy_data(self, cr, uid, id, default=None, context=None):
@@ -169,7 +169,7 @@ class project_task(osv.osv):
timebox_obj = self.pool.get('project.gtd.timebox')
if res['type'] == 'search':
tt = timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[]))
- search_extended ='''<newline/><group col="%d" expand="1" string="%s" groups="project_gtd.group_project_getting">''' % (len(tt)+7,_('Getting Things Done'))
+ search_extended ='''<newline/><group col="%d" expand="0" string="%s" groups="project_gtd.group_project_getting">''' % (len(tt)+7,_('Getting Things Done'))
search_extended += '''<filter domain="[('timebox_id','=', False)]" context="{'set_editable':True,'set_visible':True}" icon="gtk-new" string="%s"/>''' % (_('Inbox'),)
search_extended += '''<filter domain="[('state', 'in', ('draft','open','pending'))]" context="{'set_editable':True,'set_visible':True}" icon="gtk-new" string="%s"/>''' % (_('All'),)
search_extended += '''<separator orientation="vertical"/>'''
diff --git a/addons/project_gtd/project_gtd_view.xml b/addons/project_gtd/project_gtd_view.xml
index 1615319c7b9..64f6bcdfbd1 100644
--- a/addons/project_gtd/project_gtd_view.xml
+++ b/addons/project_gtd/project_gtd_view.xml
@@ -8,7 +8,8 @@
<field name="arch" type="xml">
<tree string="Context">
<field name="sequence" invisible="1"/>
- <field name="name"/>
+ <field name="name" select="1"/>
+ <field name="project_default_id" select="1"/>
</tree>
</field>
</record>
@@ -75,7 +76,7 @@
<field name="inherit_id" ref="project.view_task_tree2" />
<field name="arch" type="xml">
<field name="remaining_hours" position="after">
- <field string="xxxxxx" name="timebox_id" groups="project_gtd.group_project_getting" invisible=" not context.get('set_visible',True)"/>
+ <field string="Timebox" name="timebox_id" groups="project_gtd.group_project_getting" invisible=" not context.get('set_visible',True)"/>
<button name="prev_timebox" type="object" icon="gtk-go-back" string="Previous" states="draft,pending,open" groups="project_gtd.group_project_getting" invisible=" not context.get('set_visible',True)"/>
<button name="next_timebox" type="object" icon="gtk-go-forward" string="Next" states="draft,pending,open" groups="project_gtd.group_project_getting" invisible=" not context.get('set_visible',False)"/>
<button name="do_reopen" states="done,cancelled" string="Reactivate" type="object" icon="gtk-convert" help="For reopening the tasks" invisible="not context.get('set_visible',False)"/>
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index c7a420aa845..dd3ed036691 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -2,6 +2,8 @@
<openerp>
<data>
+ <menuitem id="menu_project_confi" name="Project Issue" parent="project.menu_definitions" sequence="1"/>
+
<record id="project_issue_categ_action" model="ir.actions.act_window">
<field name="name">Issue Categories</field>
<field name="res_model">crm.case.categ</field>
@@ -19,7 +21,8 @@
<field name="domain">[('object_id.model', '=', 'project.issue')]</field>
<field name="context">{'object_id':'project.issue'}</field>
</record>
- <menuitem action="project_issue_stage_act" id="menu_project_issue_stage_act" parent="crm.menu_crm_case_stage"/>
+
+ <menuitem action="project_issue_stage_act" name="Stages" id="menu_project_issue_stage_act" parent="menu_project_confi"/>
<record model="ir.ui.view" id="project_issue_form_view">
<field name="name">Project Issue Tracker Form</field>
@@ -184,18 +187,18 @@
<field name="arch" type="xml">
<search string="Issue Tracker Search">
<group colspan="4" col="20">
- <filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft and Open Issues" icon="terp-project" default="1"/>
- <filter string="In Progress" domain="[('state','=','open')]" help="Open Issues" icon="terp-project"/>
- <filter string="Pending" domain="[('state','=','pending')]" help="Pending Issues" icon="terp-project"/>
-
+ <filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft and Open Issues" icon="terp-check" default="1"/>
+ <filter string="In Progress" domain="[('state','=','open')]" help="Open Issues" icon="terp-camera_test"/>
+ <filter string="Pending" domain="[('state','=','pending')]" help="Pending Issues" icon="terp-gtk-media-pause"/>
+
<separator orientation="vertical"/>
-
- <filter icon="gtk-home" string=" Today "
+
+ <filter icon="terp-go-today" string=" Today "
separator="1"
domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"
help="Today's bugs"
/>
- <filter icon="gtk-media-rewind"
+ <filter icon="terp-go-week"
string=" 7 Days " separator="1"
domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d')), ('date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Bugs during last 7 days"
@@ -204,26 +207,26 @@
<field name="name" select='1' string="Subject"/>
<field name="user_id" select="1" widget="selection"/>
<field name="state" select="1">
- <filter icon="gtk-new" domain="[('state','in',('open','draft'))]" help="Current Bugs" name="current_bugs"/>
- <filter icon="gtk-yes" domain="[('state','=','open')]" help="Open Bugs"/>
+ <filter icon="terp-check" domain="[('state','in',('open','draft'))]" help="Current Bugs" name="current_bugs"/>
+ <filter icon="terp-camera_test" domain="[('state','=','open')]" help="Open Bugs"/>
</field>
<field name="project_id" select="1" widget="selection" string="Project"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
- <filter string="Stage" icon="terp-crm" domain="[]"
+ <group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
+ <filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
- <filter string="Priority" icon="terp-crm" domain="[]"
+ <filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
- <filter string="Campaign" icon="terp-crm"
+ <filter string="Campaign" icon="terp-gtk-jump-to-rtl"
domain="[]" context="{'group_by':'type_id'}" />
<separator orientation="vertical" />
- <filter string="Partner" icon="terp-crm" domain="[]"
+ <filter string="Partner" icon="terp-personal" domain="[]"
context="{'group_by':'partner_id'}" />
- <filter string="Salesman" icon="terp-crm"
+ <filter string="Salesman" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<separator orientation="vertical" />
- <filter string="Month" icon="terp-crm"
+ <filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
<separator orientation="vertical" />
</group>
@@ -285,12 +288,12 @@
<field name="arch" type="xml">
<search string="Feature Tracker Search">
<group>
- <filter icon="gtk-home" string=" Today "
+ <filter icon="terp-go-today" string=" Today "
separator="1"
domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"
help="Today's features"
/>
- <filter icon="gtk-media-rewind"
+ <filter icon="terp-go-week"
string=" 7 Days " separator="1"
domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d')), ('date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Features during last 7 days"
@@ -301,8 +304,8 @@
<field name="name" select='1' string="Feature description"/>
<field name="user_id" select="1" widget="selection"/>
<field name="state" select="1">
- <filter icon="gtk-new" domain="[('state','in',('open','draft'))]" help="Current Features" name="current_feature"/>
- <filter icon="gtk-yes" domain="[('state','=','open')]" help="Open Features"/>
+ <filter icon="terp-check" domain="[('state','in',('open','draft'))]" help="Current Features" name="current_feature"/>
+ <filter icon="terp-camera_test" domain="[('state','=','open')]" help="Open Features"/>
</field>
<field name="project_id" select="1" widget="selection" string="Project"/>
diff --git a/addons/project_issue/report/project_issue_report_view.xml b/addons/project_issue/report/project_issue_report_view.xml
index 5694d33993b..adc1b3c662f 100644
--- a/addons/project_issue/report/project_issue_report_view.xml
+++ b/addons/project_issue/report/project_issue_report_view.xml
@@ -53,25 +53,25 @@
<group col="16" colspan="8">
<!-- <filter string="This Year" name="This Year" icon="terp-hr"
domain="[('name','=',time.localtime()[0])]"/>-->
- <filter string="This Year" icon="terp-hr"
+ <filter string="This Year" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<!-- <filter string="This Month" name="This Year" icon="terp-hr"
domain="[('month','=',time.strftime('%%m'))]" />-->
- <filter string="This Month" icon="terp-hr" name="This Month"
+ <filter string="This Month" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
- <filter icon="gtk-media-rewind" string="7 Days" separator="1"
+ <filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<separator orientation="vertical" />
- <filter icon="terp-hr"
+ <filter icon="terp-document-new"
string="Draft"
domain="[('state','=','draft')]"/>
- <filter icon="terp-hr"
+ <filter icon="terp-camera_test"
string="Open"
domain="[('state','=','open')]"/>
- <filter icon="terp-hr"
+ <filter icon="terp-gtk-media-pause"
string="Pending"
domain="[('state','=','pending')]"/>
@@ -88,7 +88,7 @@
</field>
<field name="company_id" widget="selection">
- <filter icon="terp-crm"
+ <filter icon="terp-go-home"
context="{'invisible_section': False}"
domain="[('section_id.user_id.company_id','=',uid)]"
help="My company"/>
@@ -96,11 +96,11 @@
<field name="user_id" select="1" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="8">
- <filter string="User" name="User" icon="terp-sale"
+ <group expand="0" string="Group By..." colspan="4" col="8">
+ <filter string="User" name="User" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
- <filter string="Company" icon="terp-sale"
+ <filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
@@ -109,42 +109,42 @@
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
- <filter string="State" icon="terp-sale"
+ <filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
- <filter string="Category" icon="terp-sale"
+ <filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
- <filter string="Stage" icon="terp-sale" domain="[]" context="{'group_by':'stage_id'}"/>
+ <filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<separator orientation="vertical"/>
- <filter string="Project" icon="terp-sale" domain="[]" context="{'group_by':'project_id'}" />
- <filter string="Priority" icon="terp-sale" domain="[]" context="{'group_by':'priority'}" />
+ <filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}" />
+ <filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<separator orientation="vertical"/>
- <filter string="Type" icon="terp-sale" domain="[]" context="{'group_by':'type_id'}"/>
- <filter string="Task" icon="terp-sale" domain="[]" context="{'group_by':'task_id'}"/>
+ <filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type_id'}"/>
+ <filter string="Task" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'task_id'}"/>
<newline/>
- <filter string="Assigned To" icon="terp-sale" domain="[]" context="{'group_by':'assigned_to'}"/>
- <filter string="Partner" icon="terp-sale" domain="[]" context="{'group_by':'partner_id'}"/>
- <filter string="Channel" icon="terp-sale" domain="[]" context="{'group_by':'canal_id'}"/>
+ <filter string="Assigned To" icon="terp-personal" domain="[]" context="{'group_by':'assigned_to'}"/>
+ <filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
+ <filter string="Channel" icon="terp-call-start" domain="[]" context="{'group_by':'canal_id'}"/>
<separator orientation="vertical" />
<filter string="Day" icon="terp-sale"
domain="[]" context="{'group_by':'day'}"/>
- <filter string="Month" icon="terp-sale"
+ <filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
- <filter string="Year" icon="terp-sale"
+ <filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
</group>
<newline/>
<group expand="0" string="Extended options..." colspan="10" col="12" groups="base.group_extended">
- <filter icon="terp-sale"
+ <filter icon="terp-dialog-close"
string="Done"
domain="[('state','=','done')]"/>
- <filter icon="terp-sale"
+ <filter icon="terp-gtk-stop"
string="Cancel"
domain="[('state','=','cancel')]"/>
<group>
@@ -156,8 +156,8 @@
<field name="task_id"/>
<separator orientation="vertical"/>
<field name="assigned_to" widget="selection">
- <filter icon="terp-crm" help = "Project Issue Assigned To Me" domain="[('assigned_to','=',uid)]" />
- <filter icon="terp-crm" help="Non Assigned Project Issue" domain="[('assigned_to','=',False)]"/>
+ <filter icon="terp-personal" help = "Project Issue Assigned To Me" domain="[('assigned_to','=',uid)]" />
+ <filter icon="terp-personal-" help="Non Assigned Project Issue" domain="[('assigned_to','=',False)]"/>
</field>
<newline/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index 95e9099f549..212af8a30dc 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -93,7 +93,7 @@ class project_phase(osv.osv):
'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases'),
'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of phases."),
- 'duration': fields.float('Duration', required=True),
+ 'duration': fields.float('Duration', required=True, help="By default in days"),
'product_uom': fields.many2one('product.uom', 'Duration UoM', required=True, help="UoM (Unit of Measure) is the unit of measurement for Duration"),
'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks"),
'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources"),
diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml
index a2ecc604ebe..e681b0da57f 100644
--- a/addons/project_long_term/project_long_term_view.xml
+++ b/addons/project_long_term/project_long_term_view.xml
@@ -47,7 +47,7 @@
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="20">
- <filter name="resource" string="Resource" icon="terp-project" domain="[]" context="{'group_by':'resource_id'}"/>
+ <filter name="resource" string="Resource" icon="terp-folder-blue" domain="[]" context="{'group_by':'resource_id'}"/>
<filter string="Phase" icon="terp-project" domain="[]" context="{'group_by':'phase_id'}"/>
</group>
</search>
@@ -102,7 +102,7 @@
<field name="state" select="1"/>
<button string="Draft" name="set_draft" states="open" icon="gtk-indent"/>
<button string="Start Phase" name="set_open" states="pending,draft" icon="gtk-execute"/>
- <button string="Done" name="set_done" states="draft,pending,open" icon="gtk-jump-to"/>
+ <button string="Done" name="set_done" states="draft,pending,open" icon="gtk-apply"/>
<button string="Pending" name="set_pending" states="open" icon="gtk-media-pause"/>
<button string="Cancel" name="set_cancel" states="draft,open,pending" icon="gtk-cancel"/>
</group>
@@ -218,23 +218,23 @@
<field name="arch" type="xml">
<search string="Project Phases">
<group colspan="4" col="20">
- <filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft, Open and Pending Phases" icon="terp-project" default="1"/>
- <filter string="In Progress" domain="[('state','=','open')]" help="Open Phases" icon="terp-project"/>
- <filter string="Pending" domain="[('state','=','pending')]" help="Pending Phases" icon="terp-project"/>
+ <filter string="Draft" domain="[('state','=','draft')]" help="Draft Phases" icon="terp-check" default="1"/>
+ <filter string="In Progress" name="Progress" domain="[('state','=','open')]" help="Open Phases" icon="terp-camera_test"/>
+ <filter string="Pending" domain="[('state','=','pending')]" help="Pending Phases" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id" widget="selection">
- <filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-project"/>
+ <filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-folder-blue"/>
</field>
<field name="responsible_id" widget="selection"/>
<field name="date_start"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
- <filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
- <filter string="State" icon="terp-project" domain="[]" context="{'group_by':'state'}"/>
- <filter string="User" icon="terp-project" domain="[]" context="{'group_by':'responsible_id'}"/>
- <filter string="Start Date" icon="terp-project" domain="[]" context="{'group_by':'date_start'}"/>
+ <filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'responsible_id'}"/>
+ <filter string="Start Date" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
</group>
</search>
</field>
diff --git a/addons/project_long_term/wizard/project_compute_tasks_view.xml b/addons/project_long_term/wizard/project_compute_tasks_view.xml
index c89c83b3058..eff475b4f11 100644
--- a/addons/project_long_term/wizard/project_compute_tasks_view.xml
+++ b/addons/project_long_term/wizard/project_compute_tasks_view.xml
@@ -8,15 +8,13 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Compute Scheduling of Phases">
- <group colspan="4" col="4">
- <label colspan="4" string="This wizard will schedule start date, end date, and assign user to tasks for specified project" />
- <newline />
- <field colspan="4" name="project_id"/>
- </group>
- <group colspan="4" col="6">
- <button icon="gtk-cancel" special="cancel" string="_Cancel"/>
- <button icon="gtk-ok" name="compute_date" string="Compute" type="object"/>
+ <group colspan="4" height="100" width="500">
+ <field name="project_id"/>
+ <group colspan="4" col="6">
+ <button icon="gtk-cancel" special="cancel" string="_Cancel"/>
+ <button icon="gtk-ok" name="compute_date" string="Compute" type="object"/>
</group>
+ </group>
</form>
</field>
</record>
diff --git a/addons/project_mrp/mrp.py b/addons/project_mrp/mrp.py
index 350d6b006b7..6287ca3ad30 100644
--- a/addons/project_mrp/mrp.py
+++ b/addons/project_mrp/mrp.py
@@ -55,10 +55,11 @@ class mrp_procurement(osv.osv):
break
# Creating a project for task.Project is created from Procurement.
+ project_obj = self.pool.get('project.project')
proj_name = tools.ustr(so_ref)
- proj_exist_id = self.pool.get('project.project').search(cr, uid, [('name','=',proj_name)], context=context)
+ proj_exist_id = project_obj.search(cr, uid, [('name','=',proj_name)], context=context)
if not proj_exist_id:
- project_id = self.pool.get('project.project').create(cr, uid, {'name':proj_name,'category_id':analytic_account_id, 'partner_id':partner_id})
+ project_id = project_obj.create(cr, uid, {'name':proj_name, 'partner_id':partner_id})
else:
project_id = proj_exist_id[0]
diff --git a/addons/project_planning/project_planning_view.xml b/addons/project_planning/project_planning_view.xml
index 0ebbcd8e519..fd9d586f21e 100644
--- a/addons/project_planning/project_planning_view.xml
+++ b/addons/project_planning/project_planning_view.xml
@@ -162,7 +162,7 @@
<field name="arch" type="xml">
<search string="Planning by Account">
<group col="8" colspan="4">
- <filter icon="terp-project" string="Current Plannings" domain="[('date_from','&lt;=',time.strftime('%%Y-%%m-%%d')),('date_to','&gt;=',time.strftime('%%Y-%%m-%%d'))]" help="Current Plannings"/>
+ <filter icon="terp-check" string="Current Plannings" domain="[('date_from','&lt;=',time.strftime('%%Y-%%m-%%d')),('date_to','&gt;=',time.strftime('%%Y-%%m-%%d'))]" help="Current Plannings"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="code" select="1"/>
diff --git a/addons/project_timesheet/report/task_report_view.xml b/addons/project_timesheet/report/task_report_view.xml
index 35a7c9f3de6..5a653985a20 100644
--- a/addons/project_timesheet/report/task_report_view.xml
+++ b/addons/project_timesheet/report/task_report_view.xml
@@ -148,16 +148,16 @@
<field name="arch" type="xml">
<search string="Tasks by User">
<group colspan="4" col="3">
- <filter icon="terp-project" string="This Year" domain="[('year','=',time.strftime('%%Y'))]" />
- <filter icon="terp-project" string="This Month" domain="[('month','=',time.strftime('%%m'))]" />
+ <filter icon="terp-go-year" string="This Year" domain="[('year','=',time.strftime('%%Y'))]" />
+ <filter icon="terp-go-month" string="This Month" domain="[('month','=',time.strftime('%%m'))]" />
<separator orientation="vertical"/>
<field name="user_id" select="1" widget="selection"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="3">
- <filter string="User" icon="terp-project" context="{'group_by':'user_id'}" default="1" />
- <filter string="Year" icon="terp-project" context="{'group_by':'year'}" />
- <filter string="Month" icon="terp-project" context="{'group_by':'month'}" />
+ <filter string="User" icon="terp-personal" context="{'group_by':'user_id'}" default="1" />
+ <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}" />
+ <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}" />
</group>
</search>
</field>
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index b886dc60a0e..c2e871f685a 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -223,7 +223,7 @@ class purchase_order(osv.osv):
else:
raise osv.except_osv(_('Invalid action !'), _('Cannot delete Purchase Order(s) which are in %s State!' % s['state']))
- # TODO: temporary fix in 5.0, to remove in 5.2 when subflows support
+ # TODO: temporary fix in 5.0, to remove in 5.2 when subflows support
# automatically sending subflow.delete upon deletion
wf_service = netsvc.LocalService("workflow")
for id in unlink_ids:
@@ -248,7 +248,7 @@ class purchase_order(osv.osv):
return {'value':{'location_id': res, 'dest_address_id': False}}
def onchange_partner_id(self, cr, uid, ids, part):
-
+
if not part:
return {'value':{'partner_address_id': False, 'fiscal_position': False}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['default'])
@@ -264,12 +264,12 @@ class purchase_order(osv.osv):
#TODO: implement messages system
def wkf_confirm_order(self, cr, uid, ids, context={}):
todo = []
- for po in self.browse(cr, uid, ids):
+ for po in self.browse(cr, uid, ids):
if not po.order_line:
raise osv.except_osv(_('Error !'),_('You can not confirm purchase order without Purchase Order Lines.'))
- for line in po.order_line:
+ for line in po.order_line:
if line.state=='draft':
- todo.append(line.id)
+ todo.append(line.id)
current_name = self.name_get(cr, uid, ids)[0][1]
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
for id in ids:
@@ -313,13 +313,13 @@ class purchase_order(osv.osv):
wf_service = netsvc.LocalService("workflow")
for p_id in ids:
# Deleting the existing instance of workflow for PO
- wf_service.trg_delete(uid, 'purchase.order', p_id, cr)
+ wf_service.trg_delete(uid, 'purchase.order', p_id, cr)
wf_service.trg_create(uid, 'purchase.order', p_id, cr)
return True
def action_invoice_create(self, cr, uid, ids, *args):
res = False
-
+
journal_obj = self.pool.get('account.journal')
for o in self.browse(cr, uid, ids):
il = []
@@ -437,7 +437,7 @@ class purchase_order(osv.osv):
})
if order_line.move_dest_id:
self.pool.get('stock.move').write(cr, uid, [order_line.move_dest_id.id], {'location_id':order.location_id.id})
- todo_moves.append(move)
+ todo_moves.append(move)
self.pool.get('stock.move').action_confirm(cr, uid, todo_moves)
self.pool.get('stock.move').force_assign(cr, uid, todo_moves)
wf_service = netsvc.LocalService("workflow")
@@ -459,26 +459,26 @@ class purchase_order(osv.osv):
def do_merge(self, cr, uid, ids, context):
- """
- To merge similar type of purchase orders.
- Orders will only be merged if:
- * Purchase Orders are in draft
- * Purchase Orders belong to the same partner
+ """
+ To merge similar type of purchase orders.
+ Orders will only be merged if:
+ * Purchase Orders are in draft
+ * Purchase Orders belong to the same partner
* Purchase Orders are have same stock location, same pricelist
- Lines will only be merged if:
- * Order lines are exactly the same except for the quantity and unit
+ Lines will only be merged if:
+ * Order lines are exactly the same except for the quantity and unit
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
- @param ids: the ID or list of IDs
- @param context: A standard dictionary
-
+ @param ids: the ID or list of IDs
+ @param context: A standard dictionary
+
@return: new purchase order id
-
- """
- wf_service = netsvc.LocalService("workflow")
- def make_key(br, fields):
+
+ """
+ wf_service = netsvc.LocalService("workflow")
+ def make_key(br, fields):
list_key = []
for field in fields:
field_val = getattr(br, field)
@@ -496,9 +496,9 @@ class purchase_order(osv.osv):
return tuple(list_key)
# compute what the new orders should contain
-
+
new_orders = {}
-
+
for porder in [order for order in self.browse(cr, uid, ids) if order.state == 'draft']:
order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
new_order = new_orders.setdefault(order_key, ({}, []))
@@ -541,7 +541,7 @@ class purchase_order(osv.osv):
o_line[field] = field_val
o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
-
+
allorders = []
for order_key, (order_data, old_ids) in new_orders.iteritems():
@@ -601,7 +601,7 @@ class purchase_order_line(osv.osv):
'invoiced': fields.boolean('Invoiced', readonly=True),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
-
+
}
_defaults = {
'product_qty': lambda *a: 1.0,
@@ -621,7 +621,7 @@ class purchase_order_line(osv.osv):
partner_id, date_order=False, fiscal_position=False, date_planned=False,
name=False, price_unit=False, notes=False):
if not pricelist:
- raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist in the purchase form !\nPlease set one before choosing a product.'))
+ raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist or a supplier in the purchase form !\nPlease set one before choosing a product.'))
if not partner_id:
raise osv.except_osv(_('No Partner!'), _('You have to select a partner in the purchase form !\nPlease set one partner before choosing a product.'))
if not product:
@@ -692,7 +692,7 @@ class purchase_order_line(osv.osv):
return res
def action_confirm(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'confirmed'}, context)
- return True
+ return True
purchase_order_line()
class mrp_procurement(osv.osv):
@@ -700,7 +700,7 @@ class mrp_procurement(osv.osv):
_columns = {
'purchase_id': fields.many2one('purchase.order', 'Latest Requisition'),
}
-
+
def action_po_assign(self, cr, uid, ids, context={}):
""" This is action which call from workflow to assign purchase order to procurements
@return: True
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 8aa643d1c43..10c5ccd9749 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -150,12 +150,12 @@
<field name="arch" type="xml">
<search string="Search Purchase Order">
<group col='10' colspan='4'>
- <filter icon="terp-purchase" name="draft" string="Quotations" domain="[('state','=','draft')]" separator="1"/>
- <filter icon="terp-purchase" name="confirmed" string="To Approve" domain="[('state','in',('wait','confirmed'))]" separator="1"/>
- <filter icon="terp-purchase" name="approved" string="Approved" domain="[('state','in',('approved','done'))]" separator="1"/>
- <filter icon="terp-purchase" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" separator="1"/>
+ <filter icon="terp-document-new" name="draft" string="Quotations" domain="[('state','=','draft')]" separator="1"/>
+ <filter icon="terp-camera_test" name="confirmed" string="To Approve" domain="[('state','in',('wait','confirmed'))]" separator="1"/>
+ <filter icon="terp-check" name="approved" string="Approved" domain="[('state','in',('approved','done'))]" separator="1"/>
+ <filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" separator="1"/>
<separator orientation="vertical"/>
- <filter icon="terp-purchase" string="To Invoice" domain="[('invoiced','=',1)]" separator="1"/>
+ <filter icon="terp-gtk-go-back-rtl" string="To Invoice" domain="[('invoiced','=',1)]" separator="1"/>
<separator orientation="vertical"/>
<field name="name" select="1" string="Reference"/>
<field name="partner_id" select="1"/>
@@ -163,10 +163,13 @@
<field name="create_uid" select="1" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="10" groups="base.group_extended">
- <filter string="Supplier" icon="terp-purchase" domain="[]" context="{'group_by':'partner_id'}"/>
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Order Date" icon="terp-purchase" domain="[]" context="{'group_by':'date_order'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="10" groups="base.group_extended">
+ <filter string="Supplier" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'minimum_planned_date'}"/>
+ <filter string="Source Document" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
</group>
</search>
</field>
@@ -176,7 +179,7 @@
<field name="model">purchase.order</field>
<field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Purchase Order">
+ <tree colors="grey:state in ('approved','done');blue:state in ('wait','confirmed');red:state in ('except_invoice','except_picking')" string="Purchase Order">
<field name="name" string="Reference"/>
<field name="date_order" string="Order Date"/>
<field name="partner_id"/>
@@ -265,7 +268,7 @@
<tree colors="red:date_planned&lt;=current_date;black:date_planned&gt;current_date" string="Purchase Order Lines">
<field name="order_id"/>
<field name="name"/>
- <field name="date_planned" widget="date"/>
+ <field name="date_planned" widget="date" width="135"/>
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
@@ -276,6 +279,25 @@
</field>
</record>
+ <record id="purchase_order_line_search" model="ir.ui.view">
+ <field name="name">purchase.order.line.search</field>
+ <field name="model">purchase.order.line</field>
+ <field name="type">search</field>
+ <field name="arch" type="xml">
+ <search string="Search Purchase Order">
+ <group>
+ <field name='order_id'/>
+ <field name="product_id" widget="selection" />
+ </group>
+ <newline/>
+ <group expand="0" string="Group By...">
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by' : 'state'}" />
+ <filter string="Order Reference" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by' : 'product_id'}" />
+ </group>
+ </search>
+ </field>
+ </record>
+
<act_window
context="{'partner_id': active_id}"
domain="[('partner_id', '=', active_id)]"
@@ -309,6 +331,7 @@
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="purchase_order_line_search"/>
</record>
<record id="purchase_line_form_action_tree2" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
diff --git a/addons/purchase/report/purchase_report_view.xml b/addons/purchase/report/purchase_report_view.xml
index 0cfc357b51f..00c1c62f0ff 100644
--- a/addons/purchase/report/purchase_report_view.xml
+++ b/addons/purchase/report/purchase_report_view.xml
@@ -53,26 +53,26 @@
<field name="arch" type="xml">
<search string="Purchase Orders">
<group colspan="10" col="12">
- <filter icon="terp-purchase" string="This Year"
+ <filter icon="terp-go-year" string="This Year"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')),('date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in this year"/>
- <filter icon="terp-purchase" string="This Month"
+ <filter icon="terp-go-month" string="This Month"
name="month"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in this month"/>
- <filter icon="gtk-media-rewind"
+ <filter icon="terp-go-week"
string=" 7 Days "
separator="1"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Tasks during last 7 days"/>
<separator orientation="vertical"/>
- <filter icon="terp-purchase"
+ <filter icon="terp-document-new"
string="Quotations"
domain="[('state','=','draft')]"/>
- <filter icon="terp-purchase"
+ <filter icon="terp-gtk-media-pause"
string="Waiting Schedule"
domain="[('state','=','waiting_date')]"/>
- <filter icon="terp-purchase"
+ <filter icon="terp-camera_test"
string="Manual in progress"
domain="[('state','=','manual')]"/>
@@ -80,7 +80,7 @@
<field name="partner_id" string="Supplier"/>
<field name="product_id"/>
<field name="user_id" widget="selection">
- <filter icon="terp-purchase"
+ <filter icon="terp-personal-"
string="Purchase Non User"
help="Purchase Non User"
domain="[('user_id','=',False)]"/>
@@ -88,31 +88,31 @@
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="10" col="12">
- <filter string="Company" icon="terp-purchase" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
- <filter string="Warehouse" icon="terp-purchase" context="{'group_by':'warehouse_id'}"/>
- <filter string="Location" icon="terp-purchase" context="{'group_by':'location_id'}"/>
+ <group expand="0" string="Group By..." colspan="10" col="12">
+ <filter string="Company" icon="terp-go-home" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
+ <filter string="Warehouse" icon="terp-go-home" context="{'group_by':'warehouse_id'}"/>
+ <filter string="Location" icon="terp-go-home" context="{'group_by':'location_id'}"/>
<separator orientation="vertical"/>
- <filter string="Responsible" name="Responsible" icon="terp-purchase" context="{'group_by':'user_id'}"/>
- <filter string="Pricelist" icon="terp-purchase" context="{'group_by':'pricelist_id'}"/>
- <filter string="Validated by" icon="terp-purchase" context="{'group_by':'validator'}"/>
+ <filter string="Responsible" name="Responsible" icon="terp-personal" context="{'group_by':'user_id'}"/>
+ <filter string="Pricelist" icon="terp-dolar" context="{'group_by':'pricelist_id'}"/>
+ <filter string="Validated by" icon="terp-personal" context="{'group_by':'validator'}"/>
<separator orientation="vertical"/>
- <filter string="Address Contact Name" icon="terp-purchase" context="{'group_by':'partner_address_id'}"/>
- <filter string="Dest. Contact Name" icon="terp-purchase" context="{'group_by':'dest_address_id'}"/>
- <filter string="Product" icon="terp-purchase" context="{'group_by':'product_id'}"/>
+ <filter string="Address Contact Name" icon="terp-personal" context="{'group_by':'partner_address_id'}"/>
+ <filter string="Dest. Contact Name" icon="terp-gtk-jump-to-ltr" context="{'group_by':'dest_address_id'}"/>
+ <filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/>
<separator orientation="vertical"/>
- <filter string="Supplier" name="partner_id" icon="terp-purchase" context="{'group_by':'partner_id'}"/>
- <filter string="State" icon="terp-purchase" context="{'group_by':'state'}"/>
- <filter string="Fiscal Position" icon="terp-purchase" context="{'group_by':'fiscal_position'}"/>
+ <filter string="Supplier" name="partner_id" icon="terp-personal" context="{'group_by':'partner_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
+ <filter string="Fiscal Position" icon="terp-go-year" context="{'group_by':'fiscal_position'}"/>
<newline/>
- <filter string="Day" icon="terp-purchase" context="{'group_by':'day'}"/>
- <filter string="Month" icon="terp-purchase" context="{'group_by':'month'}"/>
- <filter string="Year" icon="terp-purchase" context="{'group_by':'name'}"/>
+ <filter string="Day" icon="terp-go-month" context="{'group_by':'day'}"/>
+ <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
+ <filter string="Year" icon="terp-go-year" context="{'group_by':'name'}"/>
</group>
<newline/>
<group expand="0" string="Extended filters..." colspan="10" col="12" groups="base.group_extended">
- <filter icon="terp-purchase" string="Shipping Exception" domain="[('state','=','shipping_except')]"/>
- <filter icon="terp-purchase" string="Done" domain="[('state','=','done')]"/>
+ <filter icon="terp-emblem-important" string="Shipping Exception" domain="[('state','=','shipping_except')]"/>
+ <filter icon="terp-dialog-close" string="Done" domain="[('state','=','done')]"/>
<separator orientation="vertical"/>
<field name="date_approve"/>
<separator orientation="vertical"/>
@@ -122,8 +122,8 @@
<field name="validator" widget="selection"/>
<newline/>
- <filter icon="terp-purchase" string="Invoice Exception " domain="[('state','=','invoice_except')]"/>
- <filter icon="terp-purchase" string="Cancel" domain="[('state','=','cancel')]"/>
+ <filter icon="terp-emblem-important" string="Invoice Exception " domain="[('state','=','invoice_except')]"/>
+ <filter icon="terp-gtk-stop" string="Cancel" domain="[('state','=','cancel')]"/>
<separator orientation="vertical"/>
<field name="expected_date"/>
<separator orientation="vertical"/>
diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml
index 4a4587f5f04..186815c9bc3 100644
--- a/addons/purchase_requisition/purchase_requisition_view.xml
+++ b/addons/purchase_requisition/purchase_requisition_view.xml
@@ -39,7 +39,7 @@
<field name="date_start"/>
<field name="date_end"/>
<field name="origin"/>
- <field name="company_id" groups="base.group_multi_company" widget="selection"/>
+ <field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group>
<notebook colspan="4">
@@ -65,7 +65,7 @@
<button name="tender_reset" states="done,cancel" string="Reset to Draft" type="object" icon="gtk-convert" />
<button name="tender_done" states="in_progress" string="Done" type="object" icon="gtk-jump-to" />
<button name="tender_cancel" states="draft,in_progress" string="Cancel" type="object" icon="gtk-cancel" />
- </group>
+ </group>
</page>
<page string="Quotations">
<field colspan="4" name="purchase_ids" nolabel="1" mode="tree,form">
@@ -77,8 +77,8 @@
<field name="location_id"/>
<field name="minimum_planned_date"/>
<field name="origin"/>
- <field name="state"/>
- </tree>
+ <field name="state"/>
+ </tree>
</field>
<separator colspan="4" string=""/>
<group col="8" colspan="4">
@@ -117,8 +117,8 @@
<field name="arch" type="xml">
<search string="Search Purchase Requisition">
<group col='10' colspan='4'>
- <filter icon="terp-purchase" string="Current" domain="[('state','=','draft,in_progress')]" separator="1" help="Current Purchaes Requisition"/>
- <filter icon="terp-purchase" string="Done" domain="[('state','=','done')]" separator="1" help="Current Purchaes Requisition"/>
+ <filter icon="terp-check" string="Current" domain="[('state','=','draft,in_progress')]" separator="1" help="Current Purchaes Requisition"/>
+ <filter icon="terp-dialog-close" string="Done" domain="[('state','=','done')]" separator="1" help="Current Purchaes Requisition"/>
<separator orientation="vertical"/>
<field name="name" select="1" string="Requisition Reference"/>
<field name="purchase_ids" select="1"/>
@@ -127,13 +127,13 @@
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="10" groups="base.group_extended">
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
- <separator orientation="vertical"/>
- <filter string="Date Start" icon="terp-purchase" domain="[]" context="{'group_by':'date_start'}"/>
- <filter string="Date End" icon="terp-purchase" domain="[]" context="{'group_by':'date_end'}"/>
- <separator orientation="vertical"/>
- <filter string="Origin" icon="terp-purchase" domain="[]" context="{'group_by':'origin'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="10" groups="base.group_extended">
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Date Start" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
+ <filter string="Date End" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'date_end'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Origin" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
</group>
</search>
</field>
diff --git a/addons/report_intrastat/report_intrastat_view.xml b/addons/report_intrastat/report_intrastat_view.xml
index e7a12e8ac5e..0449b097ec4 100644
--- a/addons/report_intrastat/report_intrastat_view.xml
+++ b/addons/report_intrastat/report_intrastat_view.xml
@@ -97,8 +97,8 @@
<field name="arch" type="xml">
<search string="Intrastat Data">
<group col="10" colspan="4">
- <filter string="This Year" icon="terp-stock" domain="[('name','=',time.localtime()[0])]"/>
- <filter string="This Month" icon="terp-stock" domain="[('month','=',time.localtime()[1])]"/>
+ <filter string="This Year" icon="terp-go-year" domain="[('name','=',time.localtime()[0])]"/>
+ <filter string="This Month" icon="terp-go-month" domain="[('month','=',time.localtime()[1])]"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="month" select="1"/>
diff --git a/addons/resource/resource_view.xml b/addons/resource/resource_view.xml
index 861b577ddff..df0974fd9ed 100644
--- a/addons/resource/resource_view.xml
+++ b/addons/resource/resource_view.xml
@@ -17,10 +17,10 @@
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
- <filter string="Type" icon="terp-project" domain="[]" context="{'group_by':'resource_type'}"/>
- <filter string="Company" icon="terp-project" domain="[]" context="{'group_by':'company_id'}"/>
- <filter string="User" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
+ <filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'resource_type'}"/>
+ <filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}"/>
+ <filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
@@ -55,9 +55,9 @@
<field name="resource_id" string="Resource" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20">
- <filter string="Resource" icon="terp-project" domain="[]" context="{'group_by':'resource_id'}"/>
- <filter string="Company" icon="terp-project" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
+ <group expand="0" string="Group By..." colspan="4" col="20">
+ <filter string="Resource" icon="terp-personal" domain="[]" context="{'group_by':'resource_id'}"/>
+ <filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
</group>
</search>
</field>
@@ -162,12 +162,12 @@
<field name="arch" type="xml">
<form string="Resource">
<field name="name" />
- <field name="active"/>
+ <field name="user_id" attrs="{'required':[('resource_type','=','user')]}"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
- <field name="calendar_id" widget="selection"/>
<field name="resource_type" />
- <field name="user_id" attrs="{'required':[('resource_type','=','user')]}"/>
+ <field name="calendar_id" widget="selection"/>
<field name="time_efficiency" groups="base.group_extended"/>
+ <field name="active"/>
</form>
</field>
</record>
diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py
index cad05c8dcc8..d9be5f49274 100644
--- a/addons/sale/report/sale_report.py
+++ b/addons/sale/report/sale_report.py
@@ -29,7 +29,12 @@ class sale_report(osv.osv):
_auto = False
_rec_name = 'date'
_columns = {
- 'date': fields.date('Date', readonly=True),
+ 'date': fields.date('Date Order', readonly=True),
+ 'date_confirm': fields.date('Date Confirm', readonly=True),
+ 'shipped':fields.boolean('Shipped', readonly=True),
+ 'paid':fields.float('Picked', readonly=True),
+ 'shipped_qty_1':fields.integer('Shipped Qty', readonly=True),
+ 'paid_qty':fields.float('Paid Qty', readonly=True),
'year': fields.char('Year', size=4, readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
@@ -65,45 +70,39 @@ class sale_report(osv.osv):
tools.drop_view_if_exists(cr, 'sale_report')
cr.execute("""
create or replace view sale_report as (
- select
- min(l.id) as id,
+ select el.*,
+ (select count(1) from sale_order_line where order_id = s.id) as nbr,
s.date_order as date,
+ s.date_confirm as date_confirm,
to_char(s.date_order, 'YYYY') as year,
to_char(s.date_order, 'MM') as month,
to_char(s.date_order, 'YYYY-MM-DD') as day,
- l.product_id as product_id,
- u.name as uom_name,
- sum(l.product_uom_qty * u.factor) as product_uom_qty,
s.partner_id as partner_id,
s.user_id as user_id,
s.shop_id as shop_id,
s.company_id as company_id,
- extract(epoch from avg(s.date_confirm-s.create_date))/(24*60*60)::decimal(16,2) as delay,
- sum(l.product_uom_qty*l.price_unit) as price_total,
- (sum(l.product_uom_qty*l.price_unit)/sum(l.product_uom_qty * u.factor))::decimal(16,2) as price_average,
- count(*) as nbr,
+ extract(epoch from (s.date_confirm-s.create_date))/(24*60*60)::decimal(16,2) as delay,
s.state,
- pt.categ_id,
+ s.shipped,
+ s.shipped::integer as shipped_qty_1,
s.pricelist_id as pricelist_id,
s.project_id as analytic_account_id
- from
+ from
+ sale_order s,
+ (
+ select l.id as id,
+ l.product_id as product_id,
+ u.name as uom_name,
+ sum(l.product_uom_qty * u.factor) as product_uom_qty,
+ sum(l.product_uom_qty*l.price_unit) as price_total,
+ (sum(l.product_uom_qty*l.price_unit)/sum(l.product_uom_qty * u.factor))::decimal(16,2) as price_average,
+ pt.categ_id, l.order_id
+ from
sale_order_line l
- left join sale_order s on (s.id=l.order_id)
left join product_uom u on (u.id=l.product_uom)
left join product_template pt on (pt.id=l.product_id)
- group by
- s.date_order,
- s.partner_id,
- l.product_id,
- l.product_uom,
- s.user_id,
- pt.categ_id,
- u.name,
- s.state,
- s.shop_id,
- s.company_id,
- s.pricelist_id,
- s.project_id
+ group by l.id, l.order_id, l.product_id, u.name, pt.categ_id) el
+ where s.id = el.order_id
)
""")
sale_report()
diff --git a/addons/sale/report/sale_report_view.xml b/addons/sale/report/sale_report_view.xml
index 98ae326fc14..75dd9d55642 100644
--- a/addons/sale/report/sale_report_view.xml
+++ b/addons/sale/report/sale_report_view.xml
@@ -20,12 +20,12 @@
<field name="categ_id" invisible="1"/>
<field name="nbr" sum="# of Lines"/>
<field name="product_uom_qty" sum="# of Qty"/>
+ <field name="shipped_qty_1"/>
<field name="uom_name" invisible="not context.get('set_visible',False)"/>
<field name="price_average" avg="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="delay" avg="Days to Close"/>
<field name="state" invisible="1"/>
- <field name="pricelist_id" invisible="1"/>
<field name="analytic_account_id" invisible="1"/>
</tree>
</field>
@@ -51,57 +51,62 @@
<field name="arch" type="xml">
<search string="Sales Analysis">
<group>
- <filter icon="gtk-media-rewind" string=" 365 Days "
+ <filter icon="terp-go-year" string=" 365 Days "
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')),('date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 365 days"/>
- <filter icon="gtk-media-rewind" string=" 30 Days "
+ <filter icon="terp-go-month" string=" 30 Days "
name="month"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 30 days"/>
- <filter icon="gtk-media-rewind"
+ <filter icon="terp-go-week"
string=" 7 Days "
separator="1"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Tasks during last 7 days"/>
<separator orientation="vertical"/>
- <filter icon="terp-sale"
+ <filter icon="terp-document-new"
string="Quotations"
domain="[('state','=','draft')]"/>
- <filter icon="terp-sale"
+ <filter icon="terp-dolar"
string="Sales"
domain="[('state','not in',('draft','done','cancel'))]"/>
<separator orientation="vertical"/>
+ <filter icon="terp-sale"
+ string="Picked"
+ domain="[('shipped','=',True)]"/>
+ <separator orientation="vertical"/>
<field name="partner_id"/>
<field name="product_id"/>
<field name="user_id" widget="selection">
- <filter icon="terp-sale"
+ <filter icon="terp-dolar"
string="My Sales"
help="My Sales"
domain="[('user_id','=',uid)]"/>
</field>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="10" col="12">
- <filter string="Salesman" icon="terp-sale" name="User" context="{'group_by':'user_id'}"/>
- <filter string="Shop" icon="terp-sale" context="{'group_by':'shop_id'}"/>
- <filter string="Company" icon="terp-sale" groups="base.group_multi_company" context="{'group_by':'company_id'}"/>
+ <group expand="0" string="Group By..." colspan="10" col="12">
+ <filter string="Salesman" icon="terp-personal" name="User" context="{'group_by':'user_id'}"/>
+ <filter string="Shop" icon="terp-go-home" context="{'group_by':'shop_id'}"/>
+ <filter string="Company" icon="terp-go-home" groups="base.group_multi_company" context="{'group_by':'company_id'}"/>
<separator orientation="vertical"/>
- <filter string="Product" icon="terp-sale" context="{'group_by':'product_id','set_visible':True}"/>
- <filter string="Default UoM" icon="terp-sale" context="{'group_by':'uom_name'}"/>
- <filter string="Partner" icon="terp-sale" context="{'group_by':'partner_id'}"/>
- <filter string="State" icon="terp-sale" context="{'group_by':'state'}"/>
+ <filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id','set_visible':True}"/>
+ <filter string="Default UoM" icon="terp-mrp" context="{'group_by':'uom_name'}"/>
+ <filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
- <filter string="Pricelist" icon="terp-sale" context="{'group_by':'pricelist_id'}"/>
- <filter string="Analytic Account" icon="terp-sale" context="{'group_by':'analytic_account_id'}"/>
- <filter string="Category of Product" icon="terp-sale" context="{'group_by':'categ_id'}"/>
+ <filter string="Pricelist" icon="terp-dolar" context="{'group_by':'pricelist_id'}"/>
+ <filter string="Analytic Account" icon="terp-folder-green" context="{'group_by':'analytic_account_id'}"/>
+ <filter string="Category of Product" icon="terp-stock_symbol-selection" context="{'group_by':'categ_id'}"/>
<separator orientation="vertical"/>
- <filter string="Day" icon="terp-sale" context="{'group_by':'day'}"/>
- <filter string="Month" icon="terp-sale" context="{'group_by':'month'}"/>
- <filter string="Year" icon="terp-sale" context="{'group_by':'year'}"/>
+ <filter string="Day" icon="terp-go-month" context="{'group_by':'day'}"/>
+ <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
+ <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
<field name="date"/>
+ <field name="date_confirm"/>
<separator orientation="vertical"/>
<field name="shop_id" widget="selection"/>
<field name="state"/>
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 356bd69f679..e684a1a6c1d 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -510,12 +510,12 @@ class sale_order(osv.osv):
def action_invoice_end(self, cr, uid, ids, context=None):
if context is None:
context = {}
-
+
for order in self.browse(cr, uid, ids, context=context):
for line in order.order_line:
if line.state == 'exception':
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'state': 'confirmed'}, context=context)
-
+
if order.state == 'invoice_except':
self.write(cr, uid, [order.id], {'state' : 'progress'}, context=context)
@@ -1085,7 +1085,7 @@ class sale_order_line(osv.osv):
warning = {
'title': 'No Pricelist !',
'message':
- 'You have to select a pricelist in the sale form !\n'
+ 'You have to select a pricelist or a customer in the sale form !\n'
'Please set one before choosing a product.'
}
else:
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index 1d49c105f18..4d82e8595ad 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -43,8 +43,9 @@
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_shop_tree"/>
</record>
+
<menuitem action="action_shop_form" id="menu_action_shop_form"
- parent="base.menu_base_config" sequence="70"
+ parent="product.prod_config_main" sequence="0"
groups="base.group_extended"/>
<record id="view_sale_order_calendar" model="ir.ui.view">
@@ -252,21 +253,21 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Sales Order">
- <filter icon="terp-sale" string="Quotations" domain="[('state','=','draft')]"/>
- <filter icon="terp-sale" string="Running" domain="[('state','in',('manual','progress'))]"/>
- <filter icon="terp-sale" string="Sales To Invoice" domain="[('state','=','manual')]"/>
+ <filter icon="terp-document-new" string="Quotations" domain="[('state','=','draft')]"/>
+ <filter icon="terp-check" string="Running" domain="[('state','in',('manual','progress'))]"/>
+ <filter icon="terp-gtk-go-back-rtl" string="Sales To Invoice" domain="[('state','=','manual')]"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="partner_id" select="1"/>
<field name="user_id" select="1" widget="selection"/>
<field name="date_order" select="1" string="Order date" />
<newline/>
- <group expand="1" string="Group By..." colspan="11" col="11" groups="base.group_extended">
- <filter string="Customer" icon="terp-sale" domain="[]" context="{'group_by':'partner_id'}"/>
- <filter string="Salesman" icon="terp-sale" domain="[]" context="{'group_by':'user_id'}"/>
+ <group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
+ <filter string="Customer" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
+ <filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<separator orientation="vertical"/>
- <filter string="Order Date" icon="terp-sale" domain="[]" context="{'group_by':'date_order'}"/>
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
@@ -421,21 +422,21 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Sales Order">
- <filter icon="terp-purchase" string="To Invoice" domain="[('invoiced','&lt;&gt;', 1),('state','=','done')]" separator="1"/>
+ <filter icon="terp-gtk-go-back-rtl" string="To Invoice" domain="[('invoiced','&lt;&gt;', 1),('state','=','done')]" separator="1"/>
<separator orientation="vertical"/>
<field name="order_id"/>
<field name="order_partner_id"/>
<field name="product_id"/>
<field name="salesman_id" widget="selection">
- <filter icon="terp-sale" domain="[('salesman_id','=',uid)]" help="My Sale Order Lines"/>
- <filter icon="terp-sale" domain="[('salesman_id','child_of',[uid])]" help="My Departments Sale Order Lines"/>
+ <filter icon="terp-dolar" domain="[('salesman_id','=',uid)]" help="My Sale Order Lines"/>
+ <filter icon="terp-personal+" domain="[('salesman_id','child_of',[uid])]" help="My Departments Sale Order Lines"/>
</field>
<newline/>
<group expand="context.get('report',False)" string="Group By..." colspan="9" col="8">
- <filter string="Product" icon="terp-sale" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Order" icon="terp-sale" domain="[]" context="{'group_by':'order_id'}"/>
- <filter string="Salesman" icon="terp-sale" domain="[]" context="{'group_by':'salesman_id'}"/>
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
+ <filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'salesman_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
@@ -447,14 +448,14 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Uninvoiced Lines">
- <filter icon="terp-purchase" string="Shipped"
+ <filter icon="terp-accessories-archiver" string="Shipped"
domain="[('state','=','done')]"
name="unshipped"
/>
- <filter icon="terp-purchase" string="Uninvoiced" name="uninvoiced"
+ <filter icon="terp-dolar_ok!" string="Uninvoiced" name="uninvoiced"
domain="[('invoiced','&lt;&gt;', 1),('state','&lt;&gt;','draft'),('state','&lt;&gt;','cancel')]"
/>
- <filter icon="terp-purchase" string="Sale Order"
+ <filter icon="terp-dolar" string="Sale Order"
domain="[('state','=','confirmed')]"
name="sale order"
/>
@@ -464,10 +465,10 @@
<field name="product_id"/>
<field name="state"/>
<newline />
- <group expand="1" string="Group By..." colspan="9" col="8">
- <filter string="Product" icon="terp-sale" domain="[]" context="{'group_by':'product_id'}"/>
- <filter string="Order" icon="terp-sale" domain="[]" context="{'group_by':'order_id'}"/>
- <filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By..." colspan="9" col="8">
+ <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
+ <filter string="Order" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'order_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml
index 3a703d1b5ca..bf5f1aaac52 100644
--- a/addons/sale_crm/sale_crm_view.xml
+++ b/addons/sale_crm/sale_crm_view.xml
@@ -35,7 +35,7 @@
<field name="arch" type="xml">
<field name="date_order" position="after">
<field name="section_id" default="context.get('section_id', False)" widget="selection" string="Sale Team" groups="base.group_extended">
- <filter icon="terp-crm"
+ <filter icon="terp-personal+"
domain="[('section_id','=',context.get('section_id',False))]"
groups="base.group_extended"
help="My Sales Team"/>
diff --git a/addons/sale_journal/report/sale_journal_report_view.xml b/addons/sale_journal/report/sale_journal_report_view.xml
index 9d4cdf3e368..aa0a9cf06fe 100644
--- a/addons/sale_journal/report/sale_journal_report_view.xml
+++ b/addons/sale_journal/report/sale_journal_report_view.xml
@@ -1,8 +1,8 @@
<openerp>
<data>
-
+
<!-- Sales by journal's view -->
-
+
<record model="ir.ui.view" id="view_sale_journal_report_tree">
<field name="name">sale.journal.report.tree</field>
<field name="model">sale.journal.report</field>
@@ -19,9 +19,9 @@
</tree>
</field>
</record>
-
+
<!-- sales journal graph view -->
-
+
<record id="view_sale_journal_graph" model="ir.ui.view">
<field name="name">sale.journal.report.graph</field>
<field name="model">sale.journal.report</field>
@@ -33,9 +33,9 @@
</graph>
</field>
</record>
-
- <!-- sales by journal search view -->
-
+
+ <!-- sales by journal search view -->
+
<record model="ir.ui.view" id="view_sale_journal_report_search">
<field name="name">sale.journal.report.search</field>
<field name="model">sale.journal.report</field>
@@ -43,16 +43,16 @@
<field name="arch" type="xml">
<search string="Sales by Journal">
<group col="8" colspan="4">
- <filter icon="terp-sale" string="This Year" domain="[('name','!=','')]" help="Sale journal in this year"/>
- <filter icon="terp-sale" string="This Month" domain="[('name','=',time.strftime('%%Y-%%m-01'))]" help="Sale journal in this month"/>
+ <filter icon="terp-go-year" string="This Year" domain="[('name','!=','')]" help="Sale journal in this year"/>
+ <filter icon="terp-go-month" string="This Month" domain="[('name','=',time.strftime('%%Y-%%m-01'))]" help="Sale journal in this month"/>
<separator orientation="vertical"/>
- <filter icon="terp-sale"
+ <filter icon="terp-document-new"
string="Quotations"
domain="[('state','=','draft')]"/>
- <filter icon="terp-sale"
+ <filter icon="terp-gtk-media-pause"
string="Waiting Schedule"
domain="[('state','=','waiting_date')]"/>
- <filter icon="terp-sale"
+ <filter icon="terp-camera_test"
string="In progress"
domain="[('state','=','progress')]"/>
<separator orientation="vertical"/>
@@ -62,15 +62,15 @@
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="12">
- <filter string="journal" name="journal" icon="terp-sale" context="{'group_by':'journal_id'}"/>
- <filter string="State" icon="terp-sale" context="{'group_by':'state'}"/>
+ <filter string="journal" name="journal" icon="terp-folder-orange" context="{'group_by':'journal_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
</group>
</search>
</field>
</record>
-
+
<!-- Action of sales by journal view-->
-
+
<record model="ir.actions.act_window" id="action_sale_journal_report_open_menu_all">
<field name="name">Sales by Journal</field>
<field name="res_model">sale.journal.report</field>
@@ -82,10 +82,10 @@
</record>
<menuitem name="Sales by Journal" id="menu_sale_journal_report_open_all" parent="base.next_id_64" action="action_sale_journal_report_open_menu_all"/>
-
+
<!-- picking by journal and invoice's tree view-->
-
+
<record model="ir.ui.view" id="view_sale_journal_picking_report_tree">
<field name="name">sale.journal.picking.report.tree</field>
<field name="model">sale.journal.picking.report</field>
@@ -105,9 +105,9 @@
</tree>
</field>
</record>
-
+
<!-- picking journal's graph view -->
-
+
<record id="view_sale_journal_picking_graph" model="ir.ui.view">
<field name="name">sale.journal.picking.report.graph</field>
<field name="model">sale.journal.picking.report</field>
@@ -120,9 +120,9 @@
</graph>
</field>
</record>
-
+
<!-- Picking journal search view -->
-
+
<record model="ir.ui.view" id="view_sale_journal_picking_report_search">
<field name="name">sale.journal.picking.report.search</field>
<field name="model">sale.journal.picking.report</field>
@@ -130,16 +130,16 @@
<field name="arch" type="xml">
<search string="Picking journal">
<group col="8" colspan="4">
- <filter icon="terp-sale" string="This Year" name="year" domain="[('name','=',time.strftime('%%Y'))]" help="Picking by invoice or by journal method in this year"/>
- <filter icon="terp-sale" string="This Month" name="month" domain="[('month','=',time.strftime('%%m'))]" help="Picking by invoice or by journal method in this month"/>
+ <filter icon="terp-go-year" string="This Year" name="year" domain="[('name','=',time.strftime('%%Y'))]" help="Picking by invoice or by journal method in this year"/>
+ <filter icon="terp-go-month" string="This Month" name="month" domain="[('month','=',time.strftime('%%m'))]" help="Picking by invoice or by journal method in this month"/>
<separator orientation="vertical"/>
- <filter icon="terp-stock"
+ <filter icon="terp-document-new"
string="Draft"
domain="[('state','=','draft')]"/>
- <filter icon="terp-stock"
+ <filter icon="terp-gtk-media-pause"
string="Pending"
domain="[('state','=','waiting')]"/>
- <filter icon="terp-stock"
+ <filter icon="terp-camera_test"
string="Confirmed"
domain="[('state','=','confirmed')]"/>
<separator orientation="vertical"/>
@@ -147,19 +147,19 @@
<field name="month" select="1"/>
<field name="invoice_state" select="1"/>
<field name="state" select="1"/>
- </group>
+ </group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="12">
- <filter string="Journal" icon="terp-stock" context="{'group_by':'journal_id'}"/>
- <filter string="Invoice" icon="terp-stock" context="{'group_by':'invoice_type_id'}"/>
+ <filter string="Journal" icon="terp-folder-orange" context="{'group_by':'journal_id'}"/>
+ <filter string="Invoice" icon="terp-dolar" context="{'group_by':'invoice_type_id'}"/>
<separator orientation="vertical"/>
- <filter string="Invoice state" icon="terp-stock" context="{'group_by':'invoice_state'}"/>
- <filter string="state" icon="terp-stock" context="{'group_by':'state'}"/>
+ <filter string="Invoice state" icon="terp-stock_effects-object-colorize" context="{'group_by':'invoice_state'}"/>
+ <filter string="state" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
</group>
</search>
</field>
</record>
-
+
<record model="ir.actions.act_window" id="action_sale_journal_picking_report_open">
<field name="name">Statistics on picking to invoice</field>
<field name="res_model">sale.journal.picking.report</field>
@@ -168,9 +168,9 @@
<field name="view_mode">tree,form</field>
<field name="domain">[('invoice_state','=','2binvoiced'),('invoice_type_id','=',active_id)]</field>
</record>
-
+
<!-- Action for picking journal view -->
-
+
<record model="ir.actions.act_window" id="action_sale_journal_picking_report_open_menu_all">
<field name="name">Picking Journal</field>
<field name="res_model">sale.journal.picking.report</field>
@@ -180,8 +180,8 @@
<field name="search_view_id" ref="view_sale_journal_picking_report_search"/>
<field name="context">{'search_default_month':1, 'group_by_no_leaf':1,'group_by':[]}</field>
</record>
-
+
<menuitem name="Picking journal" id="menu_invoice_type_picking_stats_open_all" parent="stock.next_id_61" action="action_sale_journal_picking_report_open_menu_all"/>
-
+
</data>
</openerp>
diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml
index 60161a1b2bf..7e4cc33b283 100644
--- a/addons/sale_journal/sale_journal_view.xml
+++ b/addons/sale_journal/sale_journal_view.xml
@@ -1,8 +1,8 @@
<openerp>
<data>
-
+
<!-- sale journal invoice Type's Form view -->
-
+
<record model="ir.ui.view" id="view_sale_journal_invoice_type_form">
<field name="name">sale_journal.invoice.type.form</field>
<field name="model">sale_journal.invoice.type</field>
@@ -17,9 +17,9 @@
</form>
</field>
</record>
-
- <!-- sale journal invoice Type's tree view -->
-
+
+ <!-- sale journal invoice Type's tree view -->
+
<record model="ir.ui.view" id="view_sale_journal_invoice_type_tree">
<field name="name">sale_journal.invoice.type.tree</field>
<field name="model">sale_journal.invoice.type</field>
@@ -31,19 +31,19 @@
</tree>
</field>
</record>
-
- <!-- Action for sale journal invoice Type -->
-
+
+ <!-- Action for sale journal invoice Type -->
+
<record model="ir.actions.act_window" id="action_definition_journal_invoice_type">
<field name="res_model">sale_journal.invoice.type</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
-
+
<!-- <menuitem name="Invoicing Methods" id="menu_definition_journal_invoice_type" parent="sale.menu_shop_configuration" action="action_definition_journal_invoice_type"/> -->
-
+
<!-- sale journal Form view -->
-
+
<record model="ir.ui.view" id="view_sale_journal_form">
<field name="name">sale_journal.sale.journal.form</field>
<field name="model">sale_journal.sale.journal</field>
@@ -57,7 +57,7 @@
<field name="date" select="1"/>
<field name="date_created" select="1"/>
<field name="date_validation" select="1"/>
- </group>
+ </group>
<notebook colspan="4">
<page string="Sales">
<field name="sale_stats_ids" colspan="4" nolabel="1">
@@ -86,9 +86,9 @@
</form>
</field>
</record>
-
- <!-- Sale journal tree view -->
-
+
+ <!-- Sale journal tree view -->
+
<record model="ir.ui.view" id="view_sale_journal_tree">
<field name="name">sale_journal.sale.journal.tree</field>
<field name="model">sale_journal.sale.journal</field>
@@ -103,9 +103,9 @@
</tree>
</field>
</record>
-
- <!-- Sale journal search view -->
-
+
+ <!-- Sale journal search view -->
+
<record model="ir.ui.view" id="view_sale_journal_search">
<field name="name">sale_journal.sale.journal.search</field>
<field name="model">sale_journal.sale.journal</field>
@@ -113,8 +113,8 @@
<field name="arch" type="xml">
<search string="Sales by Journal">
<group col="8" colspan="4">
- <filter icon="terp-sale" string="My Sale Journals" domain="[('user_id','=',uid)]" help="My Sale Journals"/>
- <filter icon="terp-sale" string="Open" domain="[('state','=','open')]" help="Open Sale Journals"/>
+ <filter icon="terp-personal" string="My Sale Journals" domain="[('user_id','=',uid)]" help="My Sale Journals"/>
+ <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Sale Journals"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="code" select="1"/>
@@ -124,20 +124,20 @@
</search>
</field>
</record>
-
- <!-- Action for sale journal view -->
-
+
+ <!-- Action for sale journal view -->
+
<record model="ir.actions.act_window" id="action_definition_journal">
<field name="res_model">sale_journal.sale.journal</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_sale_journal_search"/>
</record>
-
+
<menuitem id="menu_definition_journal" name="Sales Journals" parent="base.menu_base_config" action="action_definition_journal" sequence="60" />
-
- <!-- Inherit sales order form view -->
-
+
+ <!-- Inherit sales order form view -->
+
<record model="ir.ui.view" id="sale_journal_sale_order">
<field name="name">sale.order.journal.view.form</field>
<field name="type">form</field>
@@ -151,9 +151,9 @@
</field>
</field>
</record>
-
+
<!-- Inherit sales order tree view-->
-
+
<record model="ir.ui.view" id="sale_journal_sale_order_tree">
<field name="name">sale.order.journal.view.tree</field>
<field name="type">tree</field>
@@ -167,8 +167,8 @@
</field>
</record>
-<!-- Inherit stock picking's form view -->
-
+<!-- Inherit stock picking's form view -->
+
<record model="ir.ui.view" id="sale_journal_picking_order">
<field name="name">stock.picking.journal.view.form</field>
<field name="type">form</field>
@@ -183,8 +183,8 @@
</field>
</record>
-<!-- Inherit stock picking's tree view -->
-
+<!-- Inherit stock picking's tree view -->
+
<record model="ir.ui.view" id="sale_journal_picking_order_tree">
<field name="name">stock.picking.journal.view.tree</field>
<field name="type">tree</field>
@@ -198,9 +198,9 @@
</field>
</field>
</record>
-
+
<!-- Inherit stock picking delivery's form view.-->
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_del">
<field name="name">stock.picking.journal.view.form</field>
<field name="type">form</field>
@@ -214,9 +214,9 @@
</field>
</field>
</record>
-
+
<!-- Inherit stock picking delivery's tree view.-->
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_tree_del">
<field name="name">stock.picking.journal.view.tree</field>
<field name="type">tree</field>
@@ -230,7 +230,7 @@
</field>
</field>
</record>
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_in">
<field name="name">stock.picking.journal.view.form</field>
<field name="type">form</field>
@@ -244,7 +244,7 @@
</field>
</field>
</record>
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_tree_in">
<field name="name">stock.picking.journal.view.tree</field>
<field name="type">tree</field>
@@ -258,7 +258,7 @@
</field>
</field>
</record>
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_out">
<field name="name">stock.picking.journal.view.form</field>
<field name="type">form</field>
@@ -272,7 +272,7 @@
</field>
</field>
</record>
-
+
<record model="ir.ui.view" id="sale_journal_picking_order_tree_out">
<field name="name">stock.picking.journal.view.tree</field>
<field name="type">tree</field>
@@ -286,33 +286,33 @@
</field>
</field>
</record>
-
- <!-- Action of sale journal report in sale journal -->
-
+
+ <!-- Action of sale journal report in sale journal -->
+
<act_window name="Monthly sales"
domain="[('journal_id', '=', active_id)]"
res_model="sale.journal.report"
src_model="sale_journal.sale.journal"
id="act_sale_journal_sale_journal_2_sale_journal_sale_stats"/>
-
- <!-- Action of stock picking in picking journal -->
-
+
+ <!-- Action of stock picking in picking journal -->
+
<act_window name="Assigned picking"
domain="[('journal_id', '=', active_id),('state', '=', 'assigned')]"
res_model="stock.picking"
src_model="sale_journal.picking.journal"
id="act_sale_journal_picking_journal_2_stock_picking_assigned"/>
-
- <!-- Action of stock picking in picking journal -->
-
+
+ <!-- Action of stock picking in picking journal -->
+
<act_window name="Confirmed picking"
domain="[('journal_id', '=', active_id),('state', '=', 'confirmed')]"
res_model="stock.picking"
src_model="sale_journal.picking.journal"
id="act_sale_journal_picking_journal_2_stock_picking_confirmed"/>
-
- <!-- Action of stock picking in sale journal -->
-
+
+ <!-- Action of stock picking in sale journal -->
+
<act_window name="Assigned picking"
domain="[('sale_journal_id', '=', active_id),('state', '=', 'assigned')]"
res_model="stock.picking"
@@ -328,21 +328,21 @@
id="act_sale_journal_sale_journal_2_stock_picking_confirmed"/>
<!-- Action of sale order in sale journal -->
-
+
<act_window name="Draft sales"
domain="[('journal_id', '=', active_id),('state', '=', 'draft')]"
res_model="sale.order"
src_model="sale_journal.sale.journal"
id="act_sale_journal_sale_journal_2_sale_order_draft"/>
-
- <!-- Action of sale order in sale journal -->
-
+
+ <!-- Action of sale order in sale journal -->
+
<act_window name="Approved sales"
domain="[('journal_id', '=', active_id),('state', '=', 'approved')]"
res_model="sale.order"
src_model="sale_journal.sale.journal"
id="act_sale_journal_sale_journal_2_sale_order_approved"/>
-
+
<record id="view_partner_property_form" model="ir.ui.view">
<field name="name">res.partner.journal.property.form.inherit</field>
<field name="model">res.partner</field>
@@ -354,11 +354,11 @@
</page>
</field>
</record>
-
+
<!--=====================================================-->
<!-- picking journal view-->
<!--===================================================== -->
-
+
<record model="ir.ui.view" id="view_picking_journal_form">
<field name="name">sale_journal.picking.journal.form</field>
<field name="model">sale_journal.picking.journal</field>
@@ -373,7 +373,7 @@
<field name="date" select="1"/>
<field name="date_created" select="1"/>
<field name="date_validation" select="1"/>
- </group>
+ </group>
<notebook colspan="4">
<page string="Picking">
<field name="picking_stats_ids" colspan="4" nolabel="1"/>
@@ -392,7 +392,7 @@
</form>
</field>
</record>
-
+
<record model="ir.ui.view" id="view_picking_journal_tree">
<field name="name">sale_journal.picking.journal.tree</field>
<field name="model">sale_journal.picking.journal</field>
@@ -408,8 +408,8 @@
</field>
</record>
- <!-- Picking journal tree view -->
-
+ <!-- Picking journal tree view -->
+
<record model="ir.ui.view" id="view_picking_journal_search">
<field name="name">sale_journal.picking.journal.search</field>
<field name="model">sale_journal.picking.journal</field>
@@ -417,8 +417,8 @@
<field name="arch" type="xml">
<search string="Picking Journals">
<group col="8" colspan="4">
- <filter icon="terp-hr" string="My Picking Journals" domain="[('user_id','=',uid)]" help="My Picking Journals"/>
- <filter icon="terp-hr" string="Open" domain="[('state','=','open')]" help="Open Picking Journals"/>
+ <filter icon="terp-personal" string="My Picking Journals" domain="[('user_id','=',uid)]" help="My Picking Journals"/>
+ <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Picking Journals"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
<field name="code" select="1"/>
@@ -428,9 +428,9 @@
</search>
</field>
</record>
-
-<!-- Action of Picking journals -->
-
+
+<!-- Action of Picking journals -->
+
<record model="ir.actions.act_window" id="action_definition_picking_journal">
<field name="name">Picking Journals</field>
<field name="res_model">sale_journal.picking.journal</field>
@@ -438,16 +438,16 @@
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_picking_journal_search"/>
</record>
-
+
<menuitem name="Picking Journals" id="menu_definition_journal_picking" parent="stock.menu_stock_configuration" action="action_definition_picking_journal"/>
-
+
<record model="ir.actions.act_window" id="action_invoice_type_tree">
<field name="name">Picking by invoice_method</field>
<field name="res_model">sale_journal.invoice.type</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">tree</field>
</record>
-
+
<record model="ir.actions.act_window" id="action_invoice_type_picking_open">
<field name="name">Picking to invoice</field>
<field name="res_model">stock.picking</field>
@@ -456,7 +456,7 @@
<field name="view_mode">tree,form</field>
<field name="domain">[('state','=','done'),('invoice_state','=','2binvoiced'),('invoice_type_id','=',active_id)]</field>
</record>
-
+
<record model="ir.values" id="ir_open_invoice_type">
<field name="key2">tree_but_open</field>
<field name="model">sale_journal.invoice.type</field>
diff --git a/addons/scrum/scrum.py b/addons/scrum/scrum.py
index bccc991565f..2e3a0ca3fcb 100644
--- a/addons/scrum/scrum.py
+++ b/addons/scrum/scrum.py
@@ -29,7 +29,7 @@ class scrum_project(osv.osv):
_inherit = 'project.project'
_columns = {
'product_owner_id': fields.many2one('res.users', 'Product Owner'),
- 'sprint_size': fields.integer('Sprint Days'),
+ 'sprint_size': fields.integer('Sprint Days',help="Number of days allocated for sprint"),
'scrum': fields.integer('Is a Scrum Project'),
}
_defaults = {
@@ -105,7 +105,7 @@ class scrum_sprint(osv.osv):
'date_start': fields.date('Starting Date', required=True),
'date_stop': fields.date('Ending Date', required=True),
'project_id': fields.many2one('project.project', 'Project', required=True, domain=[('scrum','=',1)], help="If you have [?] in the project name, it means there are no analytic account linked to this project."),
- 'product_owner_id': fields.many2one('res.users', 'Product Owner', required=True),
+ 'product_owner_id': fields.many2one('res.users', 'Product Owner', required=True,help="The person who is responsible for the product"),
'scrum_master_id': fields.many2one('res.users', 'Scrum Manager', required=True),
'meeting_ids': fields.one2many('scrum.meeting', 'sprint_id', 'Daily Scrum'),
'review': fields.text('Sprint Review'),
@@ -189,7 +189,7 @@ class scrum_product_backlog(osv.osv):
for bl in self.browse(cr, uid, ids):
res.setdefault(bl.id, 0.0)
for task in bl.tasks_id:
- res[bl.id] += task.planned_hours
+ res[bl.id] += task.total_hours
return res
def button_cancel(self, cr, uid, ids, context={}):
@@ -251,7 +251,7 @@ class scrum_task(osv.osv):
result[task.id] = True
return result.keys()
_columns = {
- 'product_backlog_id': fields.many2one('scrum.product.backlog', 'Product Backlog'),
+ 'product_backlog_id': fields.many2one('scrum.product.backlog', 'Product Backlog',help="Related product backlog that contains this task. Used in SCRUM methodology"),
'sprint_id': fields.related('product_backlog_id','sprint_id', type='many2one', relation='scrum.sprint', string='Sprint',
store={
'project.task': (lambda self, cr, uid, ids, c={}: ids, ['product_backlog_id'], 10),
diff --git a/addons/scrum/scrum_view.xml b/addons/scrum/scrum_view.xml
index dc015c3f38a..be16ecfa7e5 100644
--- a/addons/scrum/scrum_view.xml
+++ b/addons/scrum/scrum_view.xml
@@ -33,7 +33,7 @@
<field name="model">scrum.product.backlog</field>
<field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Product Backlog">
+ <tree colors="grey:state in ('cancel','done');blue:state in ('pending')" string="Product Backlog">
<field name="sequence" invisible="1"/>
<field name="name"/>
<field name="project_id"/>
@@ -127,14 +127,14 @@
<search string="Product Backlogs">
<group col="10" colspan="4">
<filter default="1"
- icon="terp-project"
+ icon="terp-check"
string="Current"
name="current"
domain="['|','&amp;',('sprint_id.date_start','&lt;=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','&gt;=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open'])]"
help="Current Backlogs"/>
<separator orientation="vertical"/>
- <filter icon="terp-project" string="Draft" domain="[('state','=','draft')]" help="Draft Backlogs"/>
- <filter icon="terp-project" string="Open" domain="[('state','=','open')]" help="Open Backlogs"/>
+ <filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Backlogs"/>
+ <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Backlogs"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id" widget="selection"/>
@@ -151,11 +151,11 @@
<field name="user_id" widget="selection"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
- <filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
- <filter string="Sprint" icon="terp-project" domain="[]" context="{'group_by':'sprint_id'}"/>
- <filter string="Responsible" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
- <filter string="State" icon="terp-project" domain="[]" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
+ <filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
+ <filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
+ <filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
@@ -184,7 +184,7 @@
<field name="model">scrum.sprint</field>
<field name="type">tree</field>
<field name="arch" type="xml">
- <tree string="Scrum Sprint">
+ <tree colors="blue:state in ('pending');grey:state in ('cancel','done')" string="Scrum Sprint">
<field name="name"/>
<field name="project_id"/>
<field name="scrum_master_id"/>
@@ -260,9 +260,10 @@
<field name="arch" type="xml">
<search string="Sprints">
<group col="10" colspan="4">
- <filter name="filter_current" icon="terp-project" string="Current" domain="[('state','in',('draft','open'))]" help="Draft and open Sprints"/>
- <filter icon="terp-project" string="Draft" domain="[('state','=','draft')]" help="Draft Sprints"/>
- <filter icon="terp-project" string="Open" domain="[('state','=','open')]" help="Open Sprints"/>
+ <filter name="terp-check" icon="terp-check" string="Current" domain="[('state','in',('draft','open'))]" help="Draft and open Sprints"/>
+ <separator orientation="vertical"/>
+ <filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Sprints"/>
+ <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Sprints"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id" widget="selection"/>
@@ -270,13 +271,13 @@
<field name="date_start"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20">
- <filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
- <filter string="Masters" icon="terp-project" domain="[]" context="{'group_by':'scrum_master_id'}"/>
- <filter string="Product owner" icon="terp-project" domain="[]" context="{'group_by':'product_owner_id'}"/>
- <filter string="State" icon="terp-project" domain="[]" context="{'group_by':'state'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20">
+ <filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
+ <filter string="Managers" icon="terp-personal" domain="[]" context="{'group_by':'scrum_master_id'}"/>
+ <filter string="Product owner" icon="terp-personal" domain="[]" context="{'group_by':'product_owner_id'}"/>
+ <filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
- <filter string="Start Date" icon="terp-project" domain="[]" context="{'group_by':'date_start'}"/>
+ <filter string="Start Date" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
</group>
</search>
</field>
@@ -349,18 +350,18 @@
<field name="arch" type="xml">
<search string="Scrum Sprint">
<group col="10" colspan="4">
- <filter name="scrum_daily" icon="terp-project" string="Daily" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]" help="Daily Meetings"/>
+ <filter name="scrum_daily" icon="terp-go-today" string="Daily" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]" help="Daily Meetings"/>
<separator orientation="vertical"/>
<field name="sprint_id" widget="selection">
- <filter icon="terp-project" string="Current" domain="[('sprint_id.state','in',('draft','open'))]" help="Current Sprints" default="1"/>
+ <filter icon="terp-check" string="Current" domain="[('sprint_id.state','in',('draft','open'))]" help="Current Sprints" default="1"/>
</field>
<field name="project_id" widget="selection"/>
<field name="date"/>
</group>
<newline/>
- <group expand="1" string="Group By..." colspan="4" col="20">
- <filter string="Sprint" icon="terp-project" domain="[]" context="{'group_by':'sprint_id'}"/>
- <filter string="Date" icon="terp-project" domain="[]" context="{'group_by':'date'}"/>
+ <group expand="0" string="Group By..." colspan="4" col="20">
+ <filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
+ <filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
</group>
</search>
</field>
@@ -493,7 +494,7 @@
<field name="arch" type="xml">
<field name="project_id" position="after">
<field name="sprint_id" context="{'sprint_invisible':False}">
- <filter icon="terp-project" string="Current" context="{'sprint_invisible':False}" domain="[('sprint_id.state','in',('draft','open'))]" help="Current Sprints"/>
+ <filter icon="terp-check" string="Current" context="{'sprint_invisible':False}" domain="[('sprint_id.state','in',('draft','open'))]" help="Current Sprints"/>
</field>
</field>
</field>
@@ -506,8 +507,8 @@
<field name="inherit_id" ref="project.view_task_search_form"/>
<field name="arch" type="xml">
<xpath expr="/search/group[@string='Group By...']/filter[@string='End Date']" position="after">
- <filter string="Sprint" icon="terp-project" domain="[]" context="{'group_by':'sprint_id'}"/>
- <filter string="Backlog" icon="terp-project" domain="[]" context="{'group_by':'product_backlog_id'}"/>
+ <filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
+ <filter string="Backlog" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'product_backlog_id'}"/>
<separator orientation="vertical"/>
</xpath>
</field>
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 94d20f7a95e..6c3d09f2895 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -350,7 +350,7 @@ stock_location()
class stock_tracking(osv.osv):
_name = "stock.tracking"
_description = "Stock Tracking Lots"
-
+
def get_create_tracking_lot(self, cr, uid, ids, tracking_lot):
tracking_lot_list = self.search(cr, uid, [('name', '=', tracking_lot)],
limit=1)
@@ -893,7 +893,7 @@ class stock_picking(osv.osv):
move_obj = self.pool.get('stock.move')
if not context:
context = {}
-
+
for pick in self.browse(cr, uid, ids, context=context):
if pick.state in ['done','cancel']:
raise osv.except_osv(_('Error'), _('You cannot remove the picking which is in %s state !')%(pick.state,))
@@ -906,7 +906,7 @@ class stock_picking(osv.osv):
move_obj.action_cancel(cr, uid, ids2, ctx)
#Removing the move
move_obj.unlink(cr, uid, ids2, ctx)
-
+
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
def do_partial(self, cr, uid, ids, partial_datas, context={}):
@@ -1219,7 +1219,7 @@ class stock_move(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'product_qty': fields.float('Quantity', required=True),
- 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
+ 'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True),
'product_uos_qty': fields.float('Quantity (UOS)'),
'product_uos': fields.many2one('product.uom', 'Product UOS'),
'product_packaging': fields.many2one('product.packaging', 'Packaging', help="It specifies attributes of packaging like type, quantity of packaging,etc."),
@@ -1294,7 +1294,7 @@ class stock_move(osv.osv):
'date_planned': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.move', context=c),
- 'date_expected': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date_expected': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
def copy(self, cr, uid, id, default=None, context={}):
@@ -1648,14 +1648,14 @@ class stock_move(osv.osv):
'line_id': lines,
'ref': ref,
})
- tracking_lot = False
+ tracking_lot = False
if context:
tracking_lot = context.get('tracking_lot', False)
if tracking_lot:
rec_id = context and context.get('active_id', False)
tracking = self.pool.get('stock.tracking')
- tracking_lot = tracking.get_create_tracking_lot(cr, uid,[rec_id], tracking_lot)
-
+ tracking_lot = tracking.get_create_tracking_lot(cr, uid,[rec_id], tracking_lot)
+
self.write(cr, uid, ids, {'state': 'done', 'date_planned': time.strftime('%Y-%m-%d %H:%M:%S'), 'tracking_id': tracking_lot or False})
picking_obj = self.pool.get('stock.picking')
for pick in picking_obj.browse(cr, uid, picking_ids):
@@ -1669,7 +1669,7 @@ class stock_move(osv.osv):
def unlink(self, cr, uid, ids, context=None):
if context is None:
- context = {}
+ context = {}
for move in self.browse(cr, uid, ids, context=context):
if move.state != 'draft':
raise osv.except_osv(_('UserError'),
@@ -1877,7 +1877,7 @@ class stock_move(osv.osv):
address_id = partial_datas.get('address_id', False)
delivery_date = partial_datas.get('delivery_date', False)
tracking_lot = context.get('tracking_lot', False)
-
+
new_moves = []
complete, too_many, too_few = [], [], []
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 8eca73792a1..92653501ed3 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -341,7 +341,7 @@
<field name="location_dest_id" />
<field name="date" />
<field name="date_planned" string="Date"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field name="state"/>
</tree>
</field>
@@ -653,7 +653,7 @@
<field colspan="4" invisible="1" name="name"/>
<field invisible="1" name="date"/>
<field name="date_planned"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field name="address_id" context="{'contact_display':'partner'}"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" groups="base.group_extended"
@@ -778,7 +778,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field name="state"/>
<button
name="%(stock.track_line)d"
@@ -805,7 +805,7 @@
<field colspan="4" invisible="1" name="name"/>
<field invisible="1" name="date"/>
<field name="date_planned"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
@@ -958,7 +958,7 @@
<field name="location_id"/>
<field name="location_dest_id"/>
<field name="date_planned"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field name="state"/>
<button
name="%(stock.track_line)d"
@@ -985,7 +985,7 @@
<field colspan="4" invisible="1" name="name"/>
<field invisible="1" name="date"/>
<field name="date_planned"/>
- <field name="date_expected" string="Date Expected"/>
+ <field name="date_expected" string="Date Expected"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
@@ -1160,7 +1160,7 @@
<field groups="product.group_uos" name="product_uos_qty"/>
<field colspan="4" invisible="1" name="name" />
<field groups="base.group_extended" name="date_planned"/>
- <field name="date_expected" groups="base.group_extended" string="Date Expected"/>
+ <field name="date_expected" groups="base.group_extended" string="Date Expected"/>
<newline/>
<newline/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
@@ -1222,6 +1222,7 @@
<separator orientation="vertical"/>
<field name="name"/>
<field name="address_id"/>
+ <field name="origin"/>
<field name="company_id" widget="selection" groups="base.group_multi_company" />
</group>
<newline/>
@@ -1232,8 +1233,6 @@
<separator orientation="vertical" />
<filter string="Order Date" icon="terp-stock" domain="[]" context="{'group_by':'date'}"/>
<filter string="Expected Date" icon="terp-stock" domain="[]" context="{'group_by':'min_date'}"/>
- <separator orientation="vertical" />
- <filter string="Origin" icon="terp-stock" domain="[]" context="{'group_by':'origin'}"/>
</group>
</search>
</field>
@@ -1361,7 +1360,7 @@
<separator string="Dates &amp; Priority" colspan="2" />
<field name="date"/>
<field name="date_planned"/>
- <field name="date_expected"/>
+ <field name="date_expected"/>
<field name="priority"/>
</group>
@@ -1475,12 +1474,12 @@
<notebook colspan="4">
<page string="General Information">
<separator colspan="4" string="Move Information"/>
- <field name="location_id"/>
- <field name="location_dest_id"/>
+ <field name="location_id" widget="selection"/>
+ <field name="location_dest_id" widget="selection"/>
<field colspan="4" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
- <field name="product_uom"/>
- <field name="product_uos"/>
+ <field name="product_uom" widget="selection"/>
+ <field name="product_uos" widget="selection" groups="base.group_extended"/>
<field colspan="4" name="name"/>
<field name="date"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
@@ -1497,8 +1496,10 @@
on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id)"/>
<field name="tracking_id"/>
<newline/>
- <label/>
- <button name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill"/>
+ <group col="2" colspan="2">
+ <label/>
+ <button name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill"/>
+ </group>
<separator colspan="4" string="Move State"/>
<field name="state"/>
<group col="5" colspan="2">
@@ -1541,7 +1542,9 @@
<group expand="1" string="Group By..." colspan="4" col="8">
<filter string="Product" icon="terp-stock" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="State" icon="terp-stock" domain="[]" context="{'group_by':'state'}"/>
- <filter string="Date" icon="terp-stock" domain="[]" context="{'group_by':'date'}"/>
+ <separator orientation="vertical"/>
+ <filter string="Order Date" icon="terp-stock" domain="[]" context="{'group_by':'date'}"/>
+ <filter string="Expected Date" icon="terp-stock" domain="[]" context="{'group_by':'date_expected'}" />
</group>
</search>
</field>