[MERGE]
bzr revid: mra@tinyerp.com-20100602105812-7odoaq66n7m1f0kk bzr revid: mra@tinyerp.com-20100603032341-0euqt6n9h7303ta2 bzr revid: mra@tinyerp.com-20100603082429-8dwpjz5hdag161dq
This commit is contained in:
commit
7d239dc01d
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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="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_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>
|
||||
<blockTable colWidths="78.0,108.0,108.0,108.0,138" style="Table3a">
|
||||
<tr>
|
||||
<td>
|
||||
<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>
|
||||
|
||||
|
||||
<para style="P2">
|
||||
<font color="white"> </font>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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 -->
|
||||
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -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 -->
|
||||
|
||||
|
|
|
@ -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 -->
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import email_template_account
|
||||
import email_template
|
||||
import email_template_mailbox
|
||||
import wizard
|
||||
|
|
@ -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:
|
|
@ -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:
|
|
@ -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:
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
@ -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()
|
|
@ -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:
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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>
|
|
@ -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))
|
||||
|
|
@ -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>
|
|
@ -0,0 +1 @@
|
|||
import email_template_send_wizard
|
|
@ -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:
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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'}"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
</openerp>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
<field eval=""""ressource"""" 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>
|
||||
|
|
|
@ -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="['&', ('date_planned::date','<', 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>
|
||||
|
|
|
@ -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','<=', time.strftime('%%Y-%%m-%%d')),('date_start','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date_start','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date_start','>',(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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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="['&', ('date_planned::date','<', 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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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<0;red:bool(date_deadline) and (date_deadline<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<0 and state in ('pending');red:bool(date_deadline) and (date_deadline<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','<>',False)]" help="Show only tasks having a deadline" icon="terp-project"/>
|
||||
<filter string="Deadlines" domain="[('date_deadline','<>',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','>=',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','>=',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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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','<=', time.strftime('%%Y-%%m-%%d')),('date_start','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date_start','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date_start','>',(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"/>
|
||||
|
|
|
@ -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"/>'''
|
||||
|
|
|
@ -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)"/>
|
||||
|
|
|
@ -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','<', time.strftime('%%Y-%%m-%%d')), ('date','>=',(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','<', time.strftime('%%Y-%%m-%%d')), ('date','>=',(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"/>
|
||||
|
||||
|
|
|
@ -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','<=', time.strftime('%%Y-%%m-%%d')), ('create_date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('create_date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('create_date','>',(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')]"/>
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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','<=',time.strftime('%%Y-%%m-%%d')),('date_to','>=',time.strftime('%%Y-%%m-%%d'))]" help="Current Plannings"/>
|
||||
<filter icon="terp-check" string="Current Plannings" domain="[('date_from','<=',time.strftime('%%Y-%%m-%%d')),('date_to','>=',time.strftime('%%Y-%%m-%%d'))]" help="Current Plannings"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<=current_date;black:date_planned>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"/>
|
||||
|
|
|
@ -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','<=', time.strftime('%%Y-%%m-%%d')),('date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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="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="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
<field name="resource_type" />
|
||||
<field name="calendar_id" widget="selection"/>
|
||||
<field name="time_efficiency" groups="base.group_extended"/>
|
||||
<field name="active"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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','<=', time.strftime('%%Y-%%m-%%d')),('date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(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','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(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"/>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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','<>', 1),('state','=','done')]" separator="1"/>
|
||||
<filter icon="terp-gtk-go-back-rtl" string="To Invoice" domain="[('invoiced','<>', 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','<>', 1),('state','<>','draft'),('state','<>','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>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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="['|','&',('sprint_id.date_start','<=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','>=',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>
|
||||
|
|
|
@ -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 = [], [], []
|
||||
|
|
|
@ -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 & 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>
|
||||
|
|
Loading…
Reference in New Issue