diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py
index 39e40555f39..04f55566d40 100644
--- a/addons/account/__openerp__.py
+++ b/addons/account/__openerp__.py
@@ -18,8 +18,6 @@
# along with this program. If not, see .
#
##############################################################################
-
-
{
"name" : "Accounting and Financial Management",
"version" : "1.1",
@@ -119,6 +117,8 @@ module named account_vouchers
'report/account_account_report_view.xml',
'report/account_analytic_entries_report_view.xml',
'board_account_view.xml',
+ "wizard/account_pl_report_view.xml",
+ "wizard/account_bs_report_view.xml"
],
'demo_xml': [
#'demo/price_accuracy00.yml',
@@ -145,4 +145,4 @@ module named account_vouchers
'active': False,
'certificate': '0080331923549',
}
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/account_menuitem.xml b/addons/account/account_menuitem.xml
index 48e0e27e59a..56d83debe4c 100644
--- a/addons/account/account_menuitem.xml
+++ b/addons/account/account_menuitem.xml
@@ -2,30 +2,30 @@
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -38,7 +38,7 @@
-
+
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 272933018ad..0bc9e476601 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -801,15 +801,19 @@ class account_move_line(osv.osv):
ids = journal_pool.search(cr, uid, [])
journals = journal_pool.browse(cr, uid, ids)
all_journal = [None]
+ common_fields = {}
+ total = len(journals)
for journal in journals:
all_journal.append(journal.id)
for field in journal.view_id.columns_id:
if not field.field in fields:
- fields[field.field] = [None, journal.id]
+ fields[field.field] = [journal.id]
fld.append((field.field, field.sequence))
flds.append(field.field)
+ common_fields[field.field] = 1
else:
fields.get(field.field).append(journal.id)
+ common_fields[field.field] = common_fields[field.field] + 1
fld.append(('period_id', 3))
fld.append(('journal_id', 10))
@@ -831,6 +835,10 @@ class account_move_line(osv.osv):
for field_it in fld:
field = field_it[0]
+
+ if common_fields.get(field) == total:
+ fields.get(field).append(None)
+
if field=='state':
state = 'colors="red:state==\'draft\'"'
diff --git a/addons/account/account_report.xml b/addons/account/account_report.xml
index fc622d8f0c0..8b4aa147a95 100644
--- a/addons/account/account_report.xml
+++ b/addons/account/account_report.xml
@@ -61,21 +61,6 @@
parent="menu_tax_report"
type="wizard"/> -->
-
-
- Chart of Taxes
- account.tax.code
- [('parent_id','=',False)]
- tree
-
-
-
-
-
-
+
+ # Payment Terms
+ -->
account.payment.term.line.tree
diff --git a/addons/account/account_wizard.xml b/addons/account/account_wizard.xml
index 260876a98eb..8fa4b8065fb 100644
--- a/addons/account/account_wizard.xml
+++ b/addons/account/account_wizard.xml
@@ -1,12 +1,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
@@ -75,7 +75,7 @@
-
+
@@ -94,30 +94,30 @@
-->
-
+
-
+
-
-
+
+
-
+ -->
diff --git a/addons/account/i18n/es.po b/addons/account/i18n/es.po
index 4779ae32dd5..fdc62db3d1b 100644
--- a/addons/account/i18n/es.po
+++ b/addons/account/i18n/es.po
@@ -7,14 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2010-06-23 17:24+0000\n"
-"Last-Translator: Jordi Esteve (www.zikzakmedia.com) "
-"\n"
+"PO-Revision-Date: 2010-06-24 10:03+0000\n"
+"Last-Translator: Borja López Soilán (Pexego) \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -806,7 +805,7 @@ msgstr "Cuenta de la empresa"
#. module: account
#: wizard_view:account.subscription.generate,init:0
msgid "Generate entries before:"
-msgstr "Generar asientos antes:"
+msgstr "Generar asientos hasta:"
#. module: account
#: rml:account.analytic.account.cost_ledger:0
@@ -3680,7 +3679,7 @@ msgstr ""
#: wizard_field:account.invoice.pay,addendum,comment:0
#: wizard_field:account.invoice.pay,init,name:0
msgid "Entry Name"
-msgstr "Núm. asiento"
+msgstr "Descripción"
#. module: account
#: help:account.invoice,account_id:0
diff --git a/addons/account/i18n/gl.po b/addons/account/i18n/gl.po
index 9ae3edbd1f1..4ec34c15268 100644
--- a/addons/account/i18n/gl.po
+++ b/addons/account/i18n/gl.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2010-05-14 17:04+0000\n"
+"PO-Revision-Date: 2010-06-24 09:57+0000\n"
"Last-Translator: Borja López Soilán (Pexego) \n"
"Language-Team: Galician \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-22 04:04+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -2047,7 +2047,7 @@ msgstr ""
#. module: account
#: field:account.journal,invoice_sequence_id:0
msgid "Invoice Sequence"
-msgstr ""
+msgstr "Secuencia de factura"
#. module: account
#: wizard_view:account.automatic.reconcile,init:0
@@ -3597,7 +3597,7 @@ msgstr ""
#: wizard_field:account.invoice.pay,addendum,comment:0
#: wizard_field:account.invoice.pay,init,name:0
msgid "Entry Name"
-msgstr ""
+msgstr "Descripción"
#. module: account
#: help:account.invoice,account_id:0
@@ -5064,7 +5064,7 @@ msgstr ""
#. module: account
#: model:ir.model,name:account.model_fiscalyear_seq
msgid "Maintains Invoice sequences with Fiscal Year"
-msgstr ""
+msgstr "Mantén secuencias de facturas con exercicio fiscal"
#. module: account
#: selection:account.account.balance.report,checktype,display_account:0
diff --git a/addons/account/i18n/zh_CN.po b/addons/account/i18n/zh_CN.po
index 99660f05218..6f4caf1c7b8 100644
--- a/addons/account/i18n/zh_CN.po
+++ b/addons/account/i18n/zh_CN.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml
index 5d9bbb7e9b0..2d97f1581ca 100644
--- a/addons/account/partner_view.xml
+++ b/addons/account/partner_view.xml
@@ -70,8 +70,8 @@
2
-
-
+
+
@@ -119,7 +119,7 @@
-
+
diff --git a/addons/account/report/__init__.py b/addons/account/report/__init__.py
index ad965e04b57..ee139c3040c 100644
--- a/addons/account/report/__init__.py
+++ b/addons/account/report/__init__.py
@@ -40,5 +40,7 @@ import account_account_report
import account_entries_report
import account_analytic_entries_report
import voucher_print
+import report_bs
+import report_pl
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_report_india/report/report_balance_sheet.rml b/addons/account/report/report_balance_sheet.rml
similarity index 100%
rename from addons/account_report_india/report/report_balance_sheet.rml
rename to addons/account/report/report_balance_sheet.rml
diff --git a/addons/account_report_india/report/report_balance_sheet_horizontal.rml b/addons/account/report/report_balance_sheet_horizontal.rml
similarity index 100%
rename from addons/account_report_india/report/report_balance_sheet_horizontal.rml
rename to addons/account/report/report_balance_sheet_horizontal.rml
diff --git a/addons/account_report_india/report/report_bs.py b/addons/account/report/report_bs.py
similarity index 96%
rename from addons/account_report_india/report/report_bs.py
rename to addons/account/report/report_bs.py
index 51b2f349224..5a7294338c5 100644
--- a/addons/account_report_india/report/report_bs.py
+++ b/addons/account/report/report_bs.py
@@ -24,7 +24,7 @@ import time
import mx.DateTime
import rml_parse
from report import report_sxw
-from account_report_india.report import report_pl
+from account.report import report_pl
class report_balancesheet_horizontal(rml_parse.rml_parse):
def __init__(self, cr, uid, name, context):
@@ -195,9 +195,9 @@ class report_balancesheet_horizontal(rml_parse.rml_parse):
return comp_obj.name
report_sxw.report_sxw('report.account.balancesheet.horizontal', 'account.account',
- 'addons/account_report_india/report/report_balance_sheet_horizontal.rml',parser=report_balancesheet_horizontal,
+ 'addons/account/report/report_balance_sheet_horizontal.rml',parser=report_balancesheet_horizontal,
header=False)
report_sxw.report_sxw('report.account.balancesheet', 'account.account',
- 'addons/account_report_india/report/report_balance_sheet.rml',parser=report_balancesheet_horizontal,
+ 'addons/account/report/report_balance_sheet.rml',parser=report_balancesheet_horizontal,
header=False)
diff --git a/addons/account_report_india/report/report_pl.py b/addons/account/report/report_pl.py
similarity index 96%
rename from addons/account_report_india/report/report_pl.py
rename to addons/account/report/report_pl.py
index b8b77e08be9..c693b9940c9 100644
--- a/addons/account_report_india/report/report_pl.py
+++ b/addons/account/report/report_pl.py
@@ -170,8 +170,8 @@ class report_pl_account_horizontal(rml_parse.rml_parse):
return comp_obj.name
report_sxw.report_sxw('report.pl.account.horizontal', 'account.account',
- 'addons/account_report_india/report/report_pl_account_horizontal.rml',parser=report_pl_account_horizontal, header=False)
+ 'addons/account/report/report_pl_account_horizontal.rml',parser=report_pl_account_horizontal, header=False)
report_sxw.report_sxw('report.pl.account', 'account.account',
- 'addons/account_report_india/report/report_pl_account.rml',parser=report_pl_account_horizontal, header=False)
+ 'addons/account/report/report_pl_account.rml',parser=report_pl_account_horizontal, header=False)
diff --git a/addons/account_report_india/report/report_pl_account.rml b/addons/account/report/report_pl_account.rml
similarity index 100%
rename from addons/account_report_india/report/report_pl_account.rml
rename to addons/account/report/report_pl_account.rml
diff --git a/addons/account_report_india/report/report_pl_account_horizontal.rml b/addons/account/report/report_pl_account_horizontal.rml
similarity index 100%
rename from addons/account_report_india/report/report_pl_account_horizontal.rml
rename to addons/account/report/report_pl_account_horizontal.rml
diff --git a/addons/account/wizard/__init__.py b/addons/account/wizard/__init__.py
index c56c6c2e764..1dea8e8d4f3 100644
--- a/addons/account/wizard/__init__.py
+++ b/addons/account/wizard/__init__.py
@@ -58,6 +58,8 @@ import account_central_journal
import account_general_journal
import account_change_currency
+import account_bs_report
+import account_pl_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_report_india/wizard/account_bs_report.py b/addons/account/wizard/account_bs_report.py
similarity index 100%
rename from addons/account_report_india/wizard/account_bs_report.py
rename to addons/account/wizard/account_bs_report.py
diff --git a/addons/account_report_india/wizard/account_bs_report_view.xml b/addons/account/wizard/account_bs_report_view.xml
similarity index 100%
rename from addons/account_report_india/wizard/account_bs_report_view.xml
rename to addons/account/wizard/account_bs_report_view.xml
diff --git a/addons/account_report_india/wizard/account_pl_report.py b/addons/account/wizard/account_pl_report.py
similarity index 100%
rename from addons/account_report_india/wizard/account_pl_report.py
rename to addons/account/wizard/account_pl_report.py
diff --git a/addons/account/wizard/account_pl_report_view.xml b/addons/account/wizard/account_pl_report_view.xml
new file mode 100644
index 00000000000..b1104df8d25
--- /dev/null
+++ b/addons/account/wizard/account_pl_report_view.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+ Select period
+ account.pl.report
+ form
+
+
+
+
+
+
+ Account Profit And Loss
+ account.pl.report
+ ir.actions.act_window
+ form
+ form
+
+ new
+
+
+
+ Account Chart
+ account.pl.report
+ form
+
+
+
+
+
+
+ Select Account
+ account.pl.report
+ ir.actions.act_window
+ form
+ tree,form
+
+ {'record_id':active_id}
+ new
+
+
+
+
+
+
+
+
diff --git a/addons/account/wizard/account_subscription_generate_view.xml b/addons/account/wizard/account_subscription_generate_view.xml
index ad0e4f958d1..aeb6aef8324 100644
--- a/addons/account/wizard/account_subscription_generate_view.xml
+++ b/addons/account/wizard/account_subscription_generate_view.xml
@@ -2,37 +2,37 @@
-
+
account.subscription.generate.form
account.subscription.generate
form
-
+
- Create Subscription Entries
+ Automatic Recurring
account.subscription.generate
form
tree,form
-
- new
+
+ new
-
+
diff --git a/addons/account/wizard/account_use_model_view.xml b/addons/account/wizard/account_use_model_view.xml
index 9ff781ea53c..03ca451e509 100644
--- a/addons/account/wizard/account_use_model_view.xml
+++ b/addons/account/wizard/account_use_model_view.xml
@@ -2,88 +2,88 @@
-
+
account.use.model.form
account.use.model
form
-
+
-
- Create Entries From Models
+
+ Manual Recurring
account.use.model
form
tree,form
-
- new
- {'model_line':'model_line'}
+
+ new
+ {'model_line':'model_line'}
- Create Entries From Models
+ Manual Recurring
client_action_multi
action
account.move.line
-
+
-
+
-
+
account.use.model.open.entry.form
account.use.model
form
-
+
account.use.model.create.entry.form
account.use.model
form
-
- Create Entries From Models
+
+ Manual Recurring
account.use.model
form
tree,form
-
- new
+
+ new
-
+
diff --git a/addons/account/wizard/account_validate_move_view.xml b/addons/account/wizard/account_validate_move_view.xml
index 3ef7f16d47c..232a924dbd9 100644
--- a/addons/account/wizard/account_validate_move_view.xml
+++ b/addons/account/wizard/account_validate_move_view.xml
@@ -2,23 +2,22 @@
-
+
Validate Account Move
validate.account.move
form
-
@@ -33,38 +32,38 @@
+ name="Validate Ledger Postings"
+ parent="periodical_processing_journal_entries_validation"
+ action="action_validate_account_move"
+ id="menu_validate_account_moves"
+ />
-
+
Validate Ledger Postings
validate.account.move.lines
form
+
+
+
-
+
-
+
Validate Ledger Postings
ir.actions.act_window
validate.account.move.lines
form
form
- {'record_id' : active_id}
+ {'record_id' : active_id}
new
-
+
-
+
Validate Ledger Postings
diff --git a/addons/account_anglo_saxon/stock.py b/addons/account_anglo_saxon/stock.py
index ac0dbeadcec..6b0f367abf0 100644
--- a/addons/account_anglo_saxon/stock.py
+++ b/addons/account_anglo_saxon/stock.py
@@ -26,7 +26,7 @@ from osv import fields,osv
#----------------------------------------------------------
class stock_picking(osv.osv):
_inherit = "stock.picking"
- _description = "Packing List"
+ _description = "Picking List"
def action_invoice_create(self, cr, uid, ids, journal_id=False,
group=False, type='out_invoice', context=None):
diff --git a/addons/account_budget/i18n/es.po b/addons/account_budget/i18n/es.po
index 22fe5f58d28..fbb0fb4d22e 100644
--- a/addons/account_budget/i18n/es.po
+++ b/addons/account_budget/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_budget
diff --git a/addons/account_coda/i18n/es.po b/addons/account_coda/i18n/es.po
new file mode 100644
index 00000000000..f8fd451970f
--- /dev/null
+++ b/addons/account_coda/i18n/es.po
@@ -0,0 +1,167 @@
+# Spanish translation for openobject-addons
+# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2009-11-24 13:11+0000\n"
+"PO-Revision-Date: 2010-06-24 09:42+0000\n"
+"Last-Translator: Borja López Soilán (Pexego) \n"
+"Language-Team: Spanish \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. module: account_coda
+#: field:account.coda,journal_id:0
+#: wizard_field:account.coda_import,init,journal_id:0
+msgid "Bank Journal"
+msgstr "Diario bancario"
+
+#. module: account_coda
+#: constraint:ir.model:0
+msgid ""
+"The Object name must start with x_ and not contain any special character !"
+msgstr ""
+"¡El objeto debe empezar con x_ y no puede contener ningún carácter especial!"
+
+#. module: account_coda
+#: wizard_field:account.coda_import,extraction,note:0
+msgid "Log"
+msgstr "Registro"
+
+#. module: account_coda
+#: wizard_button:account.coda_import,extraction,open:0
+msgid "_Open Statement"
+msgstr ""
+
+#. module: account_coda
+#: model:ir.module.module,shortdesc:account_coda.module_meta_information
+msgid "Account CODA"
+msgstr ""
+
+#. module: account_coda
+#: field:account.coda,name:0
+msgid "Coda file"
+msgstr ""
+
+#. module: account_coda
+#: wizard_view:account.coda_import,init:0
+msgid "Clic on 'New' to select your file :"
+msgstr ""
+
+#. module: account_coda
+#: model:ir.actions.wizard,name:account_coda.wizard_account_coda_import
+msgid "Import Coda File"
+msgstr ""
+
+#. module: account_coda
+#: constraint:ir.actions.act_window:0
+msgid "Invalid model name in the action definition."
+msgstr "Nombre de modelo inválido en la definición de acción."
+
+#. module: account_coda
+#: field:account.coda,note:0
+msgid "Import log"
+msgstr "Registro de importación"
+
+#. module: account_coda
+#: wizard_field:account.coda_import,init,def_receivable:0
+msgid "Default receivable Account"
+msgstr "Cuenta a recibir por defecto"
+
+#. module: account_coda
+#: model:ir.module.module,description:account_coda.module_meta_information
+msgid ""
+"Module provides functionality to import\n"
+" bank statements from .csv file.\n"
+" Import coda file wizard is used to import bank statements."
+msgstr ""
+
+#. module: account_coda
+#: wizard_button:account.coda_import,extraction,end:0
+msgid "_Close"
+msgstr "_Cerrar"
+
+#. module: account_coda
+#: field:account.coda,statement_id:0
+msgid "Generated Bank Statement"
+msgstr "Extracto bancario generado"
+
+#. module: account_coda
+#: view:account.coda:0
+#: model:ir.actions.act_window,name:account_coda.act_account_payment_account_bank_statement
+#: model:ir.actions.act_window,name:account_coda.action_account_coda
+msgid "Coda import"
+msgstr ""
+
+#. module: account_coda
+#: field:account.coda,user_id:0
+msgid "User"
+msgstr "Usuario"
+
+#. module: account_coda
+#: constraint:ir.ui.view:0
+msgid "Invalid XML for View Architecture!"
+msgstr "¡XML inválido para la estructura de la vista!"
+
+#. module: account_coda
+#: model:ir.model,name:account_coda.model_account_coda
+msgid "coda for an Account"
+msgstr ""
+
+#. module: account_coda
+#: wizard_field:account.coda_import,init,def_payable:0
+msgid "Default Payable Account"
+msgstr "Cuenta a pagar por defecto"
+
+#. module: account_coda
+#: model:ir.ui.menu,name:account_coda.menu_account_coda
+msgid "Coda Statements"
+msgstr ""
+
+#. module: account_coda
+#: model:ir.ui.menu,name:account_coda.menu_account_coda_wizard
+msgid "Import Coda Statements"
+msgstr ""
+
+#. module: account_coda
+#: wizard_button:account.coda_import,init,extraction:0
+msgid "_Ok"
+msgstr "_Aceptar"
+
+#. module: account_coda
+#: wizard_view:account.coda_import,extraction:0
+#: wizard_view:account.coda_import,init:0
+msgid "Import Coda Statement"
+msgstr ""
+
+#. module: account_coda
+#: field:account.bank.statement,coda_id:0
+msgid "Coda"
+msgstr ""
+
+#. module: account_coda
+#: wizard_view:account.coda_import,extraction:0
+msgid "Results :"
+msgstr "Resultados :"
+
+#. module: account_coda
+#: wizard_field:account.coda_import,init,coda:0
+msgid "Coda File"
+msgstr ""
+
+#. module: account_coda
+#: field:account.coda,date:0
+msgid "Import Date"
+msgstr "Fecha de importación"
+
+#. module: account_coda
+#: wizard_view:account.coda_import,init:0
+msgid "Select your bank journal :"
+msgstr "Seleccione su diario bancario :"
diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py
index 3ba9301a365..89353993a85 100644
--- a/addons/account_followup/wizard/account_followup_print.py
+++ b/addons/account_followup/wizard/account_followup_print.py
@@ -272,7 +272,7 @@ class account_followup_print_all(osv.osv_memory):
data['followup_id'] = 'followup_id' in context and context['followup_id'] or False
date = 'date' in context and context['date'] or data['date']
for id in to_update.keys():
- if to_update[id]['partner_id'] in data['partner_ids'][0][2]:
+ if to_update[id]['partner_id'] in data['partner_ids']:
cr.execute(
"UPDATE account_move_line "\
"SET followup_line_id=%s, followup_date=%s "\
diff --git a/addons/account_payment/i18n/es.po b/addons/account_payment/i18n/es.po
index 96b1e86eeb9..0248b3f62c5 100644
--- a/addons/account_payment/i18n/es.po
+++ b/addons/account_payment/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_payment
diff --git a/addons/account_report_india/__init__.py b/addons/account_report_india/__init__.py
deleted file mode 100644
index f8c96cb3c42..00000000000
--- a/addons/account_report_india/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-import report
-import wizard
diff --git a/addons/account_report_india/report/__init__.py b/addons/account_report_india/report/__init__.py
deleted file mode 100755
index 5bcdacfefaf..00000000000
--- a/addons/account_report_india/report/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-import report_bs
-import report_pl
diff --git a/addons/account_report_india/report/rml_parse.py b/addons/account_report_india/report/rml_parse.py
deleted file mode 100755
index 2d2c1d5a763..00000000000
--- a/addons/account_report_india/report/rml_parse.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-from report import report_sxw
-import xml.dom.minidom
-import os, time
-import osv
-import re
-import tools
-import pooler
-import re
-import sys
-
-
-class rml_parse(report_sxw.rml_parse):
- def __init__(self, cr, uid, name, context):
- super(rml_parse, self).__init__(cr, uid, name, context=None)
- self.localcontext.update({
- 'comma_me': self.comma_me,
- 'format_date': self._get_and_change_date_format_for_swiss,
- 'strip_name' : self._strip_name,
- 'explode_name' : self._explode_name,
- })
-
- def comma_me(self,amount):
- #print "#" + str(amount) + "#"
- if not amount:
- amount = 0.0
- if type(amount) is float :
- amount = str('%.2f'%amount)
- else :
- amount = str(amount)
- if (amount == '0'):
- return ' '
- orig = amount
- new = re.sub("^(-?\d+)(\d{3})", "\g<1>'\g<2>", amount)
- if orig == new:
- return new
- else:
- return self.comma_me(new)
-
- def _ellipsis(self, string, maxlen=100, ellipsis = '...'):
- ellipsis = ellipsis or ''
- try:
- return string[:maxlen - len(ellipsis) ] + (ellipsis, '')[len(string) < maxlen]
- except Exception, e:
- return False
-
- def _strip_name(self, name, maxlen=50):
- return self._ellipsis(name, maxlen, '...')
-
- def _get_and_change_date_format_for_swiss (self,date_to_format):
- date_formatted=''
- if date_to_format:
- date_formatted = strptime (date_to_format,'%Y-%m-%d').strftime('%d.%m.%Y')
- return date_formatted
-
- def _explode_name(self,chaine,length):
- # We will test if the size is less then account
- full_string = ''
- if (len(str(chaine)) <= length):
- return chaine
- #
- else:
- chaine = unicode(chaine,'utf8').encode('iso-8859-1')
- rup = 0
- for carac in chaine:
- rup = rup + 1
- if rup == length:
- full_string = full_string + '\n'
- full_string = full_string + carac
- rup = 0
- else:
- full_string = full_string + carac
-
- return full_string
-
- def makeAscii(self,str):
- try:
- Stringer = str.encode("utf-8")
- except UnicodeDecodeError:
- try:
- Stringer = str.encode("utf-16")
- except UnicodeDecodeError:
- print "UTF_16 Error"
- Stringer = str
- else:
- return Stringer
- else:
- return Stringer
- return Stringer
-
- def explode_this(self,chaine,length):
- #chaine = self.repair_string(chaine)
- chaine = rstrip(chaine)
- ast = list(chaine)
- i = length
- while i <= len(ast):
- ast.insert(i,'\n')
- i = i + length
- chaine = str("".join(ast))
- return chaine
-
- def repair_string(self,chaine):
- ast = list(chaine)
- UnicodeAst = []
- _previouslyfound = False
- i = 0
- #print str(ast)
- while i < len(ast):
- elem = ast[i]
- try:
- Stringer = elem.encode("utf-8")
- except UnicodeDecodeError:
- to_reencode = elem + ast[i+1]
- print str(to_reencode)
- Good_char = to_reencode.decode('utf-8')
- UnicodeAst.append(Good_char)
- i += i +2
- else:
- UnicodeAst.append(elem)
- i += i + 1
- return "".join(UnicodeAst)
-
- def ReencodeAscii(self,str):
- print sys.stdin.encoding
- try:
- Stringer = str.decode("ascii")
- except UnicodeEncodeError:
- print "REENCODING ERROR"
- return str.encode("ascii")
- except UnicodeDecodeError:
- print "DECODING ERROR"
- return str.encode("ascii")
- else:
- print Stringer
- return Stringer
-
- def _add_header(self, node, header=1):
- if header==2:
- rml_head = self.rml_header2
- else:
- rml_head = self.rml_header
- rml_head = rml_head.replace('',''' [[company.logo]] ''')
- return True
-
-
-
diff --git a/addons/account_report_india/wizard/account_pl_report_view.xml b/addons/account_report_india/wizard/account_pl_report_view.xml
deleted file mode 100644
index e4ef4c5434e..00000000000
--- a/addons/account_report_india/wizard/account_pl_report_view.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
- Select period
- account.pl.report
- form
-
-
-
-
-
-
- Account Profit And Loss
- account.pl.report
- ir.actions.act_window
- form
- form
-
- new
-
-
-
- Account Chart
- account.pl.report
- form
-
-
-
-
-
-
- Select Account
- account.pl.report
- ir.actions.act_window
- form
- tree,form
-
- {'record_id':active_id}
- new
-
-
-
-
-
-
-
-
diff --git a/addons/auction/i18n/el.po b/addons/auction/i18n/el.po
index ee0853b10fc..6e0265c94c5 100644
--- a/addons/auction/i18n/el.po
+++ b/addons/auction/i18n/el.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2010-06-24 02:48+0000\n"
+"PO-Revision-Date: 2010-06-24 22:06+0000\n"
"Last-Translator: Panayiotis Konstantinidis \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: auction
@@ -182,7 +182,7 @@ msgstr "ΦΠΑ"
#. module: auction
#: view:auction.lots:0
msgid "Statements"
-msgstr ""
+msgstr "Καταστάσεις"
#. module: auction
#: xsl:flagey.huissier:0
@@ -244,33 +244,34 @@ msgstr "Σύγχρονη Τέχνη"
#: view:auction.lots:0
#: view:report.unclassified.objects:0
msgid "Ref"
-msgstr ""
+msgstr "Αναφορά"
#. module: auction
#: field:report.auction.view,nseller:0
msgid "No of sellers"
-msgstr ""
+msgstr "Αριθμός πωλητών"
#. module: auction
#: selection:auction.lots.send.aie,date_ask,lang:0
msgid "ned"
-msgstr ""
+msgstr "Κανονική ισοδύναμη απόκλιση"
#. module: auction
#: constraint:hr.attendance:0
msgid "Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)"
msgstr ""
+"Σφάλμα: Η Είσοδος (ή Έξοδος) πρέπει να ακολουθείται από Έξοδο (Είσοδο)"
#. module: auction
#: view:auction.lots:0
#: field:report.buyer.auction,total_price:0
msgid "Total Adj."
-msgstr ""
+msgstr "Συνολική προσαρμογή"
#. module: auction
#: field:report.auction.view2,obj_margin_procent:0
msgid "Net margin (%)"
-msgstr ""
+msgstr "Καθαρό περιθώριο (%)"
#. module: auction
#: selection:auction.lots,state:0
@@ -278,28 +279,28 @@ msgstr ""
#: selection:report.seller.auction,state:0
#: selection:report.unclassified.objects,state:0
msgid "Unsold"
-msgstr ""
+msgstr "Αδιάθετο"
#. module: auction
#: view:auction.dates:0
msgid "Dates"
-msgstr ""
+msgstr "Ημερομηνίες"
#. module: auction
#: constraint:product.template:0
msgid "Error: UOS must be in a different category than the UOM"
-msgstr ""
+msgstr "Error: UOS must be in a different category than the UOM"
#. module: auction
#: rml:auction.total.rml:0
msgid "Items"
-msgstr ""
+msgstr "Αντικείμενα"
#. module: auction
#: model:account.tax,name:auction.auction_tax5
#: field:auction.dates,seller_costs:0
msgid "Seller Costs"
-msgstr ""
+msgstr "Έξοδα πωλητών"
#. module: auction
#: view:auction.bid:0
@@ -309,75 +310,75 @@ msgstr ""
#: model:ir.actions.report.xml,name:auction.bid_auction
#: model:ir.ui.menu,name:auction.menu_action_bid_open
msgid "Bids"
-msgstr ""
+msgstr "Προσφορές"
#. module: auction
#: model:ir.ui.menu,name:auction.auction_all_objects_menu
msgid "All objects"
-msgstr ""
+msgstr "Όλα τα αντικείμενα"
#. module: auction
#: model:ir.actions.act_window,name:auction.action_auction_buyer_reporting_all2
msgid "Buyer's auction for all months"
-msgstr ""
+msgstr "Πληστηριασμοί αγοραστή για όλους τους μήνες"
#. module: auction
#: field:auction.bid,contact_tel:0
msgid "Contact"
-msgstr ""
+msgstr "Επικοινωνία"
#. module: auction
#: field:report.auction.view,obj_ret:0
#: field:report.object.encoded,obj_ret:0
#: field:report.object.encoded.manager,obj_ret:0
msgid "# obj ret"
-msgstr ""
+msgstr "Αριθμός αντικειμένων που επεστράφησαν"
#. module: auction
#: wizard_button:auction.lots.sms_send,init,send:0
msgid "Send SMS"
-msgstr ""
+msgstr "Αποστολή SMS"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Cont. Art/Painting"
-msgstr ""
+msgstr "Cont. Τέχνη/Ζωγραφική"
#. module: auction
#: field:auction.lots,sel_inv_id:0
msgid "Seller Invoice"
-msgstr ""
+msgstr "Τιμολόγιο πωλητή"
#. module: auction
#: view:auction.dates:0
msgid "Commissions"
-msgstr ""
+msgstr "Προμήθειες"
#. module: auction
#: wizard_button:auction.lots.numerotate,search,init:0
msgid "Back"
-msgstr ""
+msgstr "Πίσω"
#. module: auction
#: model:ir.actions.act_window,name:auction.action_all_objects_unsold
msgid "Unsold objects"
-msgstr ""
+msgstr "Αδιάθετα αντικείμενα"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_all_objects_sold1
msgid "Sold Objects"
-msgstr ""
+msgstr "Πουλημένα αντικείμενα"
#. module: auction
#: view:report.buyer.auction2:0
#: view:report.seller.auction2:0
msgid "Sum net margin"
-msgstr ""
+msgstr "Σύνολο καθαρού περιθωρίου"
#. module: auction
#: view:auction.deposit:0
msgid "Deposit Border Form"
-msgstr ""
+msgstr "Κατάθεση φόρμας συνόρων"
#. module: auction
#: field:auction.bid,bid_lines:0
@@ -385,12 +386,12 @@ msgstr ""
#: rml:bids.lots:0
#: model:ir.model,name:auction.model_auction_bid_line
msgid "Bid"
-msgstr ""
+msgstr "Προσφορά"
#. module: auction
#: wizard_field:auction.lots.send.aie,date_ask,lang:0
msgid "Langage"
-msgstr ""
+msgstr "Γλώσσα"
#. module: auction
#: field:auction.bid_line,lot_id:0
@@ -398,17 +399,17 @@ msgstr ""
#: view:auction.lots:0
#: model:ir.model,name:auction.model_auction_lots
msgid "Object"
-msgstr ""
+msgstr "Αντικείμενο"
#. module: auction
#: model:ir.actions.wizard,name:auction.wizard_map_user
msgid "Map buyer username to Partners"
-msgstr ""
+msgstr "Καταγραφή του ονόματος χρήστη στους 'Συνεργάτες'"
#. module: auction
#: wizard_field:auction.lots.numerotate,search,lot_num:0
msgid "Inventory Number"
-msgstr ""
+msgstr "Αριθμός απογραφής"
#. module: auction
#: wizard_button:auction.lots.buyer_map,check,end:0
@@ -416,17 +417,17 @@ msgstr ""
#: wizard_button:auction.lots.numerotate,search,end:0
#: wizard_button:auction.lots.numerotate_cont,init,end:0
msgid "Exit"
-msgstr ""
+msgstr "Έξοδος"
#. module: auction
#: field:report.buyer.auction2,net_revenue:0
msgid "Net Revenue"
-msgstr ""
+msgstr "Καθαρό έσοδο"
#. module: auction
#: view:report.buyer.auction:0
msgid "Auction buyer reporting form view"
-msgstr ""
+msgstr "Έντυπο έκθεσης άποψης των αγοραστών δημοπρασιών"
#. module: auction
#: field:auction.dates,state:0
@@ -436,17 +437,17 @@ msgstr ""
#: field:report.seller.auction,state:0
#: field:report.unclassified.objects,state:0
msgid "Status"
-msgstr ""
+msgstr "Κατάσταση"
#. module: auction
#: model:ir.actions.wizard,name:auction.wizard_sms
msgid "SMS Send"
-msgstr ""
+msgstr "Αποστολή γραπτού μηνύματος"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Cartoons"
-msgstr ""
+msgstr "Αντίκες/Γελοιογραφίες"
#. module: auction
#: view:auction.lots:0
@@ -454,42 +455,43 @@ msgstr ""
#: selection:report.seller.auction,state:0
#: selection:report.unclassified.objects,state:0
msgid "Sold"
-msgstr ""
+msgstr "Πουλημένο"
#. module: auction
#: constraint:hr.employee:0
msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr ""
+"Σφάλμα! Δε μπορείται να δημιουργήσετε αναδρομική ιεραρχία στους εργαζομένους"
#. module: auction
#: field:auction.bid_line,name:0
msgid "Bid date"
-msgstr ""
+msgstr "Ημερομηνία προσφορών"
#. module: auction
#: field:auction.dates,acc_expense:0
msgid "Expense Account"
-msgstr ""
+msgstr "Λογαριασμός Εξόδων"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_wizard_emporte
msgid "Deliveries Management"
-msgstr ""
+msgstr "Διαχείριση Παραδόσεων"
#. module: auction
#: field:auction.lots,obj_desc:0
msgid "Object Description"
-msgstr ""
+msgstr "Περιγραφή αντικειμένου"
#. module: auction
#: selection:auction.deposit,method:0
msgid "Contact the Seller"
-msgstr ""
+msgstr "Επικοινωνήστε με τον πωλητή"
#. module: auction
#: view:auction.lots:0
msgid "Auction Objects"
-msgstr ""
+msgstr "Δημοπρατημένα αντικείμενα"
#. module: auction
#: field:auction.lots,gross_revenue:0
@@ -497,60 +499,60 @@ msgstr ""
#: field:report.object.encoded.manager,gross_revenue:0
#: field:report.seller.auction2,gross_revenue:0
msgid "Gross revenue"
-msgstr ""
+msgstr "Μικτό έσοδο"
#. module: auction
#: view:report.seller.auction2:0
msgid "Auction reporting2 form view"
-msgstr ""
+msgstr "Έντυπο αναφοράς άποψης Δημοπρασίας"
#. module: auction
#: model:ir.actions.wizard,name:auction.wizard_pay
msgid "Pay objects of the buyer"
-msgstr ""
+msgstr "Πληρωμή αντικειμένων του αγοραστή"
#. module: auction
#: view:report.deposit.border:0
msgid "Depositer's statistics"
-msgstr ""
+msgstr "Στατιστικά αποταμιευτή"
#. module: auction
#: view:auction.lots:0
msgid "Buyer information"
-msgstr ""
+msgstr "Πληροφορίες Αγοραστή"
#. module: auction
#: model:ir.model,name:auction.model_report_seller_auction
msgid "Auction Reporting on seller view"
-msgstr ""
+msgstr "Έντυπο αναφοράς άποψης των πωλητών για τη δημοπρασία"
#. module: auction
#: field:auction.lots,name2:0
msgid "Short Description (2)"
-msgstr ""
+msgstr "Σύντομη περιγραφή (2)"
#. module: auction
#: model:ir.model,name:auction.model_auction_dates
msgid "auction.dates"
-msgstr ""
+msgstr "Δημοπρασίες.Ημερομηνίες"
#. module: auction
#: rml:auction.total.rml:0
#: model:ir.ui.menu,name:auction.auction_buyers_menu
msgid "Buyers"
-msgstr ""
+msgstr "Αγοραστές"
#. module: auction
#: wizard_field:auction.pay.buy,init,amount:0
#: wizard_field:auction.pay.buy,init,amount2:0
#: wizard_field:auction.pay.buy,init,amount3:0
msgid "Amount paid"
-msgstr ""
+msgstr "Ποσό που πληρώθηκε"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_report_latest_doposit_tree
msgid "My Latest Deposits"
-msgstr ""
+msgstr "Οι Τελευταίες Καταθέσεις μου"
#. module: auction
#: field:auction.lots,lot_est1:0
@@ -559,105 +561,105 @@ msgstr ""
#: field:report.auction.view,min_est:0
#: field:report.unclassified.objects,lot_est1:0
msgid "Minimum Estimation"
-msgstr ""
+msgstr "Ελάχιστος υπολογισμός"
#. module: auction
#: view:auction.dates:0
msgid "Accounting"
-msgstr ""
+msgstr "Λογιστική"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_buyer_allmonth_view2
msgid "Buyer's Revenues"
-msgstr ""
+msgstr "Έσοδα του Αγοραστή"
#. module: auction
#: model:ir.model,name:auction.model_report_auction_adjudication
msgid "report_auction_adjudication"
-msgstr ""
+msgstr "Αναφορά_δημοπρασίες_Διαγωνισμοί"
#. module: auction
#: field:auction.bid_line,price:0
msgid "Maximum Price"
-msgstr ""
+msgstr "Μέγιστη τιμή"
#. module: auction
#: selection:auction.lots.send.aie,date_ask,lang:0
msgid "eng"
-msgstr ""
+msgstr "Αγγλική"
#. module: auction
#: view:report.buyer.auction2:0
msgid "Auction buyer reporting tree view2"
-msgstr ""
+msgstr "Προβολή δέντρου εκθέσεων αγοραστή δημοπρασιών"
#. module: auction
#: wizard_view:auction.lots.sms_send,init:0
msgid "Bulk SMS send"
-msgstr ""
+msgstr "Μαζική αποστολή γραπτών μηνυμάτων"
#. module: auction
#: wizard_view:auction.taken,init:0
msgid "Select lots which are Sold"
-msgstr ""
+msgstr "Επιλέξτε παρτίδες που έχουν πουληθεί"
#. module: auction
#: field:auction.lots,statement_id:0
msgid "Payment"
-msgstr ""
+msgstr "Πληρωμή"
#. module: auction
#: selection:auction.lots.send.aie,date_ask,lang:0
msgid "fr"
-msgstr ""
+msgstr "Γαλλική"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Old weapons and militaria"
-msgstr ""
+msgstr "Αντίκες/ παλαιά όπλα και στρατιωτικά είδη"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Oriental Arts/Chineese furnitures"
-msgstr ""
+msgstr "Αντίκεςς/Ανατολίτικη τέχνη/Κινέζικα έπιπλα"
#. module: auction
#: selection:auction.deposit,method:0
msgid "Keep until sold"
-msgstr ""
+msgstr "Διατήρηση μέχρι να πουληθεί"
#. module: auction
#: wizard_button:auction.lots.numerotate,init,choice:0
#: wizard_button:auction.lots.send.aie,init,date_ask:0
#: wizard_button:auction.lots.send.aie.results,init,date_ask:0
msgid "Continue"
-msgstr ""
+msgstr "Συνεχίστε"
#. module: auction
#: field:report.object.encoded,obj_num:0
#: field:report.object.encoded.manager,obj_num:0
msgid "# of Encoded obj."
-msgstr ""
+msgstr "Πλήθος κωδικοποιημένων αντικειμένων"
#. module: auction
#: xsl:report.auction.vnd_bordereau:0
msgid "List N."
-msgstr ""
+msgstr "Λίστα Ν."
#. module: auction
#: field:report.deposit.border,moy_est:0
msgid "Avg. Est"
-msgstr ""
+msgstr "Μέσος υπολογισμός"
#. module: auction
#: rml:auction.total.rml:0
msgid "# of sellers:"
-msgstr ""
+msgstr "Πλήθος πωλητών:"
#. module: auction
#: constraint:product.product:0
msgid "Error: Invalid ean code"
-msgstr ""
+msgstr "Σφάλμα: Άκυρος κωδικός EAN"
#. module: auction
#: model:ir.module.module,description:auction.module_meta_information
@@ -668,26 +670,33 @@ msgid ""
" Delivery Management. \n"
" "
msgstr ""
+"Αυτή η μονάδα παρέχει λειτουργικότητα στη \n"
+" Διαχείριση καλλιτεχνών, αντικειμένων, πωλητών, αγοραστών και "
+"δημοπρασίας.\n"
+" Διαχείριση προσφορών, ιχνηλάτιση πουλημένων, πληρωμένων και απλήρωτων "
+"αντικειμένων.\n"
+" Διαχείριση παραδόσεων. \n"
+" "
#. module: auction
#: rml:auction.total.rml:0
msgid "# of items taken away:"
-msgstr ""
+msgstr "πλήθος αντικειμένων που παραδόθηκαν:"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_auction_allmonth_view1
msgid "Auction's Summary"
-msgstr ""
+msgstr "Περίληψη Δημοπρασίας"
#. module: auction
#: rml:buyer.list:0
msgid "%)"
-msgstr ""
+msgstr "%)"
#. module: auction
#: wizard_view:auction.lots.able,init:0
msgid "Confirmation set taken away"
-msgstr ""
+msgstr "Επιβεβαίωση αυτών που έχουν σταλθεί"
#. module: auction
#: wizard_field:auction.lots.make_invoice,init,objects:0
@@ -696,7 +705,7 @@ msgstr ""
#: wizard_field:auction.lots.send.aie.results,date_ask,objects:0
#: field:report.deposit.border,nb_obj:0
msgid "# of objects"
-msgstr ""
+msgstr "ΠΛήθος αντικειμένων"
#. module: auction
#: field:auction.lots,lot_est2:0
@@ -705,42 +714,42 @@ msgstr ""
#: field:report.auction.view,max_est:0
#: field:report.unclassified.objects,lot_est2:0
msgid "Maximum Estimation"
-msgstr ""
+msgstr "Μέγιστος υπολογισμός"
#. module: auction
#: field:auction.lots,buyer_price:0
msgid "Buyer price"
-msgstr ""
+msgstr "Τιμή αγοραστή"
#. module: auction
#: model:ir.actions.wizard,name:auction.auction_wizard_payer_sel
msgid "Mark as paid for seller"
-msgstr ""
+msgstr "Σημειώστε το ως πληρωμένο για τον πωλητή"
#. module: auction
#: model:ir.actions.report.xml,name:auction.seller_form_id
msgid "Seller List"
-msgstr ""
+msgstr "Λίστα πωλητών"
#. module: auction
#: field:auction.lots,is_ok:0
msgid "Buyer's payment"
-msgstr ""
+msgstr "ΠΛηρωμή αγοραστή"
#. module: auction
#: view:auction.dates:0
msgid "Close + Create all invoices"
-msgstr ""
+msgstr "Κλείσιμο + Δημιουργεία όλων των τιμολογίων"
#. module: auction
#: model:ir.actions.wizard,name:auction.auction_catalog_flagy
msgid "Auction Catalog Flagey"
-msgstr ""
+msgstr "Κατάλογος δημοπρασιών Flagey"
#. module: auction
#: field:auction.lot.history,price:0
msgid "Withdrawn price"
-msgstr ""
+msgstr "Απόσυρση τιμής"
#. module: auction
#: model:account.tax,name:auction.auction_tax4
diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py
index 80166298edb..3a56f15ed3d 100644
--- a/addons/audittrail/audittrail.py
+++ b/addons/audittrail/audittrail.py
@@ -25,6 +25,7 @@ from tools.translate import _
import ir
import pooler
import time
+import tools
class audittrail_rule(osv.osv):
"""
@@ -33,25 +34,28 @@ class audittrail_rule(osv.osv):
_name = 'audittrail.rule'
_description = "Audittrail Rule"
_columns = {
- "name": fields.char("Rule Name", size=32, required=True),
- "object_id": fields.many2one('ir.model', 'Object', required=True),
- "user_id": fields.many2many('res.users', 'audittail_rules_users',
- 'user_id', 'rule_id', 'Users'),
- "log_read": fields.boolean("Log reads"),
- "log_write": fields.boolean("Log writes"),
- "log_unlink": fields.boolean("Log deletes"),
- "log_create": fields.boolean("Log creates"),
- "state": fields.selection((("draft", "Draft"),
- ("subscribed", "Subscribed")),
- "State", required=True),
- "action_id": fields.many2one('ir.actions.act_window', "Action ID"),
+ "name": fields.char("Rule Name", size=32, required=True),
+ "object_id": fields.many2one('ir.model', 'Object', required=True),
+ "user_id": fields.many2many('res.users', 'audittail_rules_users',
+ 'user_id', 'rule_id', 'Users', help="if User is not added then it will applicable for all users"),
+ "log_read": fields.boolean("Log Reads"),
+ "log_write": fields.boolean("Log Writes"),
+ "log_unlink": fields.boolean("Log Deletes"),
+ "log_create": fields.boolean("Log Creates"),
+ "log_action": fields.boolean("Log Action"),
+ "log_workflow": fields.boolean("Log Workflow"),
+ "state": fields.selection((("draft", "Draft"),
+ ("subscribed", "Subscribed")),
+ "State", required=True),
+ "action_id": fields.many2one('ir.actions.act_window', "Action ID"),
+
}
_defaults = {
- 'state': lambda *a: 'draft',
- 'log_create': lambda *a: 1,
- 'log_unlink': lambda *a: 1,
- 'log_write': lambda *a: 1,
+ 'state': lambda *a: 'draft',
+ 'log_create': lambda *a: 1,
+ 'log_unlink': lambda *a: 1,
+ 'log_write': lambda *a: 1,
}
_sql_constraints = [
@@ -65,7 +69,7 @@ class audittrail_rule(osv.osv):
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Auddittrail Rule’s IDs.
- @return: True
+ @return: True
"""
obj_action = self.pool.get('ir.actions.act_window')
obj_model = self.pool.get('ir.model.data')
@@ -74,20 +78,20 @@ class audittrail_rule(osv.osv):
obj = self.pool.get(thisrule.object_id.model)
if not obj:
raise osv.except_osv(
- _('WARNING: audittrail is not part of the pool'),
+ _('WARNING: audittrail is not part of the pool'),
_('Change audittrail depends -- Setting rule as DRAFT'))
self.write(cr, uid, [thisrule.id], {"state": "draft"})
val = {
- "name": 'View Log',
- "res_model": 'audittrail.log',
- "src_model": thisrule.object_id.model,
+ "name": 'View Log',
+ "res_model": 'audittrail.log',
+ "src_model": thisrule.object_id.model,
"domain": "[('object_id','=', " + str(thisrule.object_id.id) + "), ('res_id', '=', active_id)]"
}
- id = obj_action.create(cr, uid, val)
- self.write(cr, uid, [thisrule.id], {"state": "subscribed", "action_id": id})
+ action_id = obj_action.create(cr, uid, val)
+ self.write(cr, uid, [thisrule.id], {"state": "subscribed", "action_id": action_id})
keyword = 'client_action_relate'
- value = 'ir.actions.act_window,' + str(id)
+ value = 'ir.actions.act_window,' + str(action_id)
res = obj_model.ir_set(cr, uid, 'action', keyword, 'View_log_' + thisrule.object_id.model, [thisrule.object_id.model], value, replace=True, isobject=True, xml_id=False)
#End Loop
return True
@@ -98,7 +102,7 @@ class audittrail_rule(osv.osv):
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Auddittrail Rule’s IDs.
- @return: True
+ @return: True
"""
obj_action = self.pool.get('ir.actions.act_window')
val_obj = self.pool.get('ir.values')
@@ -127,17 +131,28 @@ class audittrail_log(osv.osv):
_name = 'audittrail.log'
_description = "Audittrail Log"
+ def _name_get_resname(self, cr, uid, ids, *args):
+ data = {}
+ for resname in self.browse(cr, uid, ids,[]):
+ model_object = resname.object_id
+ res_id = resname.res_id
+ if model_object and res_id:
+ model_pool = self.pool.get(model_object.model)
+ res = model_pool.read(cr, uid, res_id, ['name'])
+ data[resname.id] = res['name']
+ else:
+ data[resname.id] = False
+ return data
+
_columns = {
- "name": fields.char("Name", size=32),
- "object_id": fields.many2one('ir.model', 'Object'),
- "user_id": fields.many2one('res.users', 'User'),
- "method": fields.selection((('read', 'Read'),
- ('write', 'Write'),
- ('unlink', 'Delete'),
- ('create', 'Create')), "Method"),
- "timestamp": fields.datetime("Date"),
- "res_id": fields.integer('Resource Id'),
- "line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'),
+ "name": fields.char("Resource Name",size=64),
+ # "name": fields.function(_name_get_resname, type='char', string='Resource Name', method=True),
+ "object_id": fields.many2one('ir.model', 'Object'),
+ "user_id": fields.many2one('res.users', 'User'),
+ "method": fields.char("Method", size=64),
+ "timestamp": fields.datetime("Date"),
+ "res_id": fields.integer('Resource Id'),
+ "line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'),
}
_defaults = {
@@ -155,14 +170,14 @@ class audittrail_log_line(osv.osv):
_name = 'audittrail.log.line'
_description = "Log Line"
_columns = {
- 'field_id': fields.many2one('ir.model.fields', 'Fields', required=True),
- 'log_id': fields.many2one('audittrail.log', 'Log'),
- 'log': fields.integer("Log ID"),
- 'old_value': fields.text("Old Value"),
- 'new_value': fields.text("New Value"),
- 'old_value_text': fields.text('Old value Text'),
- 'new_value_text': fields.text('New value Text'),
- 'field_description': fields.char('Field Description', size=64),
+ 'field_id': fields.many2one('ir.model.fields', 'Fields', required=True),
+ 'log_id': fields.many2one('audittrail.log', 'Log'),
+ 'log': fields.integer("Log ID"),
+ 'old_value': fields.text("Old Value"),
+ 'new_value': fields.text("New Value"),
+ 'old_value_text': fields.text('Old value Text'),
+ 'new_value_text': fields.text('New value Text'),
+ 'field_description': fields.char('Field Description', size=64),
}
audittrail_log_line()
@@ -170,276 +185,366 @@ audittrail_log_line()
class audittrail_objects_proxy(osv_pool):
""" Uses Object proxy for auditing changes on object of subscribed Rules"""
-
- def get_value_text(self, cr, uid, field_name, values, object, context=None):
+
+ def get_value_text(self, cr, uid, field_name, values, model, context=None):
"""
Gets textual values for the fields
e.g.: For field of type many2one it gives its name value instead of id
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
- @param field_name: List of fields for text values
- @param values: Values for field to be converted into textual values
- @return: values: List of textual values for given fields
+ @param field_name: List of fields for text values
+ @param values: Values for field to be converted into textual values
+ @return: values: List of textual values for given fields
"""
if not context:
context = {}
pool = pooler.get_pool(cr.dbname)
- f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', field_name), ('model_id', '=', object.id)])
- if f_id:
- field = pool.get('ir.model.fields').read(cr, uid, f_id)[0]
- model = field['relation']
+ field_pool = pool.get('ir.model.fields')
+ model_pool = pool.get('ir.model')
+ obj_pool = pool.get(model.model)
+ if obj_pool._inherits:
+ inherits_ids = model_pool.search(cr, uid, [('model', '=', obj_pool._inherits.keys()[0])])
+ field_ids = field_pool.search(cr, uid, [('name', '=', field_name), ('model_id', 'in', (model.id, inherits_ids[0]))])
+ else:
+ field_ids = field_pool.search(cr, uid, [('name', '=', field_name), ('model_id', '=', model.id)])
+ field_id = field_ids and field_ids[0] or False
+ assert field_id, _("'%s' field is not exits in '%s' model" %(field_name, model.model))
- if field['ttype'] == 'many2one':
- if values:
- if type(values) == tuple:
- values = values[0]
- val = pool.get(model).read(cr, uid, [values], [pool.get(model)._rec_name])
- if val:
- return val[0][pool.get(model)._rec_name]
- elif field['ttype'] == 'many2many':
- value = []
- if values:
- for id in values:
- val = pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
- if val:
- value.append(val[0][pool.get(model)._rec_name])
- return value
+ field = field_pool.read(cr, uid, field_id)
+ relation_model = field['relation']
+ relation_model_pool = relation_model and pool.get(relation_model) or False
- elif field['ttype'] == 'one2many':
- if values:
- value = []
- for id in values:
- val = pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
+ if field['ttype'] == 'many2one':
+ res = False
+ relation_id = False
+ if values and type(values) == tuple:
+ relation_id = values[0]
+ if relation_id and relation_model_pool:
+ relation_model_object = relation_model_pool.read(cr, uid, relation_id, [relation_model_pool._rec_name])
+ res = relation_model_object[relation_model_pool._rec_name]
+ return res
- if val:
- value.append(val[0][pool.get(model)._rec_name])
- return value
- return values
+ elif field['ttype'] in ('many2many','one2many'):
+ res = []
+ for relation_model_object in relation_model_pool.read(cr, uid, values, [relation_model_pool._rec_name]):
+ res.append(relation_model_object[relation_model_pool._rec_name])
+ return res
- def create_log_line(self, cr, uid, id, object, lines=[]):
+ return values
+
+ def create_log_line(self, cr, uid, log_id, model, lines=[]):
"""
Creates lines for changed fields with its old and new values
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
- @param object: Object who's values are being changed
+ @param model: Object who's values are being changed
@param lines: List of values for line is to be created
"""
-
pool = pooler.get_pool(cr.dbname)
- obj = pool.get(object.model)
+ obj_pool = pool.get(model.model)
+ model_pool = pool.get('ir.model')
+ field_pool = pool.get('ir.model.fields')
+ log_line_pool = pool.get('audittrail.log.line')
#start Loop
for line in lines:
- if obj._inherits:
- inherits_ids = pool.get('ir.model').search(cr, uid, [('model', '=', obj._inherits.keys()[0])])
- f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', (object.id, inherits_ids[0]))])
+ if obj_pool._inherits:
+ inherits_ids = model_pool.search(cr, uid, [('model', '=', obj_pool._inherits.keys()[0])])
+ field_ids = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', (model.id, inherits_ids[0]))])
else:
- f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', '=', object.id)])
- if f_id:
- fields = pool.get('ir.model.fields').read(cr, uid, f_id)
- old_value = 'old_value' in line and line['old_value'] or ''
- new_value = 'new_value' in line and line['new_value'] or ''
- old_value_text = 'old_value_text' in line and line['old_value_text'] or ''
- new_value_text = 'new_value_text' in line and line['new_value_text'] or ''
-
- if old_value_text == new_value_text:
- continue
- if fields[0]['ttype'] == 'many2one':
- if type(old_value) == tuple:
- old_value = old_value[0]
- if type(new_value) == tuple:
- new_value = new_value[0]
- vals = {
- "log_id": id,
- "field_id": f_id[0],
- "old_value": old_value,
- "new_value": new_value,
- "old_value_text": old_value_text,
- "new_value_text": new_value_text,
- "field_description": fields[0]['field_description']
- }
- line_id = pool.get('audittrail.log.line').create(cr, uid, vals)
- cr.commit()
- #End Loop
+ field_ids = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', '=', model.id)])
+ field_id = field_ids and field_ids[0] or False
+ assert field_id, _("'%s' field is not exits in '%s' model" %(line['name'], model.model))
+
+ field = field_pool.read(cr, uid, field_id)
+ old_value = 'old_value' in line and line['old_value'] or ''
+ new_value = 'new_value' in line and line['new_value'] or ''
+ old_value_text = 'old_value_text' in line and line['old_value_text'] or ''
+ new_value_text = 'new_value_text' in line and line['new_value_text'] or ''
+
+ if old_value_text == new_value_text:
+ continue
+ if field['ttype'] == 'many2one':
+ if type(old_value) == tuple:
+ old_value = old_value[0]
+ if type(new_value) == tuple:
+ new_value = new_value[0]
+ vals = {
+ "log_id": log_id,
+ "field_id": field_id,
+ "old_value": old_value,
+ "new_value": new_value,
+ "old_value_text": old_value_text,
+ "new_value_text": new_value_text,
+ "field_description": field['field_description']
+ }
+ line_id = log_line_pool.create(cr, uid, vals)
+ #End Loop
return True
- def log_fct(self, db, uid, object, method, fct_src, *args):
+
+ def log_fct(self, db, uid, model, method, fct_src, *args):
"""
Logging function: This function is performs logging oprations according to method
@param db: the current database
@param uid: the current user’s ID for security checks,
@param object: Object who's values are being changed
- @param method: method to log: create, read, write, unlink
+ @param method: method to log: create, read, write, unlink
@param fct_src: execute method of Object proxy
-
- @return: Returns result as per method of Object proxy
+
+ @return: Returns result as per method of Object proxy
"""
- logged_uids = []
+ res2 = args
pool = pooler.get_pool(db)
cr = pooler.get_db(db).cursor()
- obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)])
- model_object = pool.get('ir.model').browse(cr, uid, obj_ids)[0]
+ resource_pool = pool.get(model)
+ log_pool = pool.get('audittrail.log')
+ model_pool = pool.get('ir.model')
+
+ model_ids = model_pool.search(cr, uid, [('model', '=', model)])
+ model_id = model_ids and model_ids[0] or False
+ assert model_id, _("'%s' Model is not exits..." %(model))
+ model = model_pool.browse(cr, uid, model_id)
+
if method in ('create'):
- res_id = fct_src(db, uid, object, method, *args)
+ res_id = fct_src(db, uid, model.model, method, *args)
cr.commit()
- new_value = pool.get(model_object.model).read(cr, uid, [res_id], args[0].keys())[0]
- if 'id' in new_value:
- del new_value['id']
- if not logged_uids or uid in logged_uids:
- resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
- resource_name = resource_name and resource_name[0][1] or ''
- vals = {
- "method": method,
- "object_id": model_object.id,
- "user_id": uid, "res_id": res_id,
- "name": resource_name
- }
- id = pool.get('audittrail.log').create(cr, uid, vals)
- lines = []
- for field in new_value:
- if new_value[field]:
- line = {
- 'name': field,
- 'new_value': new_value[field],
- 'new_value_text': self.get_value_text(cr, uid, field, new_value[field], model_object)
- }
- lines.append(line)
- self.create_log_line(cr, uid, id, model_object, lines)
+ resource = resource_pool.read(cr, uid, res_id, args[0].keys())
+ vals = {
+ "method": method,
+ "object_id": model.id,
+ "user_id": uid,
+ "res_id": resource['id'],
+ }
+ if 'id' in resource:
+ del resource['id']
+ log_id = log_pool.create(cr, uid, vals)
+ lines = []
+ for field in resource:
+ line = {
+ 'name': field,
+ 'new_value': resource[field],
+ 'new_value_text': self.get_value_text(cr, uid, field, resource[field], model)
+ }
+ lines.append(line)
+ self.create_log_line(cr, uid, log_id, model, lines)
+
cr.commit()
cr.close()
return res_id
- if method in ('write'):
- res_ids = args[0]
- for res_id in res_ids:
- old_values = pool.get(model_object.model).read(cr, uid, res_id, args[1].keys())
- old_values_text = {}
- for field in args[1].keys():
- old_values_text[field] = self.get_value_text(cr, uid, field, old_values[field], model_object)
- res = fct_src(db, uid, object, method, *args)
- cr.commit()
- if res:
- new_values = pool.get(model_object.model).read(cr, uid, res_ids, args[1].keys())[0]
- if not logged_uids or uid in logged_uids:
- resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
- resource_name = resource_name and resource_name[0][1] or ''
- id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
- lines = []
- for field in args[1].keys():
- if args[1].keys():
- line = {
- 'name': field,
- 'new_value': field in new_values and new_values[field] or '',
- 'old_value': field in old_values and old_values[field] or '',
- 'new_value_text': self.get_value_text(cr, uid, field, new_values[field], model_object),
- 'old_value_text': old_values_text[field]
- }
- lines.append(line)
- cr.commit()
- self.create_log_line(cr, uid, id, model_object, lines)
- cr.close()
- return res
-
- if method in ('read'):
+ elif method in ('read'):
res_ids = args[0]
old_values = {}
- res = fct_src(db, uid, object, method, *args)
+ res = fct_src(db, uid, model.model, method, *args)
if type(res) == list:
-
for v in res:
old_values[v['id']] = v
else:
old_values[res['id']] = res
for res_id in old_values:
- if not logged_uids or uid in logged_uids:
- resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
- resource_name = resource_name and resource_name[0][1] or ''
- id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
- lines = []
- for field in old_values[res_id]:
- if old_values[res_id][field]:
- line = {
- 'name': field,
- 'old_value': old_values[res_id][field],
- 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
- }
- lines.append(line)
- cr.commit()
- self.create_log_line(cr, uid, id, model_object, lines)
+ vals = {
+ "method": method,
+ "object_id": model.id,
+ "user_id": uid,
+ "res_id": res_id,
+
+ }
+ log_id = log_pool.create(cr, uid, vals)
+ lines = []
+ for field in old_values[res_id]:
+ line = {
+ 'name': field,
+ 'old_value': old_values[res_id][field],
+ 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model)
+ }
+ lines.append(line)
+
+ self.create_log_line(cr, uid, log_id, model, lines)
+
cr.close()
return res
- if method in ('unlink'):
+ elif method in ('unlink'):
res_ids = args[0]
old_values = {}
for res_id in res_ids:
- old_values[res_id] = pool.get(model_object.model).read(cr, uid, res_id, [])
+ old_values[res_id] = resource_pool.read(cr, uid, res_id)
for res_id in res_ids:
- if not logged_uids or uid in logged_uids:
- resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
- resource_name = resource_name and resource_name[0][1] or ''
- id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
- lines = []
- for field in old_values[res_id]:
- if old_values[res_id][field]:
- line = {
- 'name': field,
- 'old_value': old_values[res_id][field],
- 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
- }
- lines.append(line)
- cr.commit()
- self.create_log_line(cr, uid, id, model_object, lines)
- res = fct_src(db, uid, object, method, *args)
+ vals = {
+ "method": method,
+ "object_id": model.id,
+ "user_id": uid,
+ "res_id": res_id,
+
+ }
+ log_id = log_pool.create(cr, uid, vals)
+ lines = []
+ for field in old_values[res_id]:
+ if field in ('id'):
+ continue
+ line = {
+ 'name': field,
+ 'old_value': old_values[res_id][field],
+ 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model)
+ }
+ lines.append(line)
+
+ self.create_log_line(cr, uid, log_id, model, lines)
+ res = fct_src(db, uid, model.model, method, *args)
+ cr.commit()
cr.close()
return res
- cr.close()
+ else:
+ res_ids = args[0]
+ old_values = {}
+ fields = []
+ if len(args)>1 and type(args[1]) == dict:
+ fields = args[1].keys()
+ if type(res_ids) in (long, int):
+ res_ids = [res_ids]
+ if res_ids:
+ for resource in resource_pool.read(cr, uid, res_ids):
+ resource_id = resource['id']
+ if 'id' in resource:
+ del resource['id']
+ old_values_text = {}
+ old_value = {}
+ for field in resource.keys():
+ old_value[field] = resource[field]
+ old_values_text[field] = self.get_value_text(cr, uid, field, resource[field], model)
+ old_values[resource_id] = {'text':old_values_text, 'value': old_value}
- def execute(self, db, uid, object, method, *args, **kw):
+ res = fct_src(db, uid, model.model, method, *args)
+ cr.commit()
+
+ if res_ids:
+ for resource in resource_pool.read(cr, uid, res_ids):
+ resource_id = resource['id']
+ if 'id' in resource:
+ del resource['id']
+ vals = {
+ "method": method,
+ "object_id": model.id,
+ "user_id": uid,
+ "res_id": resource_id,
+ }
+
+
+ log_id = log_pool.create(cr, uid, vals)
+ lines = []
+ for field in resource.keys():
+ line = {
+ 'name': field,
+ 'new_value': resource[field],
+ 'old_value': old_values[resource_id]['value'][field],
+ 'new_value_text': self.get_value_text(cr, uid, field, resource[field], model),
+ 'old_value_text': old_values[resource_id]['text'][field]
+ }
+ lines.append(line)
+
+ self.create_log_line(cr, uid, log_id, model, lines)
+ cr.commit()
+ cr.close()
+ return res
+ return True
+
+
+
+ def execute(self, db, uid, model, method, *args, **kw):
"""
Overrides Object Proxy execute method
@param db: the current database
@param uid: the current user’s ID for security checks,
@param object: Object who's values are being changed
- @param method: method to log: create, read, write, unlink
-
- @return: Returns result as per method of Object proxy
+ @param method: get any method and create log
+
+ @return: Returns result as per method of Object proxy
"""
pool = pooler.get_pool(db)
+ model_pool = pool.get('ir.model')
+ rule_pool = pool.get('audittrail.rule')
cr = pooler.get_db(db).cursor()
cr.autocommit(True)
logged_uids = []
fct_src = super(audittrail_objects_proxy, self).execute
- def my_fct(db, uid, object, method, *args):
- field = method
+ def my_fct(db, uid, model, method, *args):
rule = False
- obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)])
- for obj_name in pool.obj_list():
- if obj_name == 'audittrail.rule':
+ model_ids = model_pool.search(cr, uid, [('model', '=', model)])
+ model_id = model_ids and model_ids[0] or False
+
+ for model_name in pool.obj_list():
+ if model_name == 'audittrail.rule':
rule = True
if not rule:
- return fct_src(db, uid, object, method, *args)
- if not obj_ids:
- return fct_src(db, uid, object, method, *args)
- rule_ids = pool.get('audittrail.rule').search(cr, uid, [('object_id', '=', obj_ids[0]), ('state', '=', 'subscribed')])
- if not rule_ids:
- return fct_src(db, uid, object, method, *args)
+ return fct_src(db, uid, model, method, *args)
+ if not model_id:
+ return fct_src(db, uid, model, method, *args)
- for thisrule in pool.get('audittrail.rule').browse(cr, uid, rule_ids):
+ rule_ids = rule_pool.search(cr, uid, [('object_id', '=', model_id), ('state', '=', 'subscribed')])
+ if not rule_ids:
+ return fct_src(db, uid, model, method, *args)
+
+ for thisrule in rule_pool.browse(cr, uid, rule_ids):
for user in thisrule.user_id:
logged_uids.append(user.id)
if not logged_uids or uid in logged_uids:
- if field in ('read', 'write', 'create', 'unlink'):
- if getattr(thisrule, 'log_' + field):
- return self.log_fct(db, uid, object, method, fct_src, *args)
- return fct_src(db, uid, object, method, *args)
- res = my_fct(db, uid, object, method, *args)
+ if method in ('read', 'write', 'create', 'unlink'):
+ if getattr(thisrule, 'log_' + method):
+ return self.log_fct(db, uid, model, method, fct_src, *args)
+
+ elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create'):
+ if thisrule.log_action:
+ return self.log_fct(db, uid, model, method, fct_src, *args)
+
+ return fct_src(db, uid, model, method, *args)
+ res = my_fct(db, uid, model, method, *args)
cr.close()
return res
+
+ def exec_workflow(self, db, uid, model, method, *args, **argv):
+ pool = pooler.get_pool(db)
+ cr = pooler.get_db(db).cursor()
+ cr.autocommit(True)
+ logged_uids = []
+ fct_src = super(audittrail_objects_proxy, self).exec_workflow
+ field = method
+ rule = False
+ model_pool = pool.get('ir.model')
+ rule_pool = pool.get('audittrail.rule')
+ model_ids = model_pool.search(cr, uid, [('model', '=', model)])
+ for obj_name in pool.obj_list():
+ if obj_name == 'audittrail.rule':
+ rule = True
+ if not rule:
+ cr.close()
+ return super(audittrail_objects_proxy, self).exec_workflow(db, uid, model, method, *args, **argv)
+ if not model_ids:
+ cr.close()
+ return super(audittrail_objects_proxy, self).exec_workflow(db, uid, model, method, *args, **argv)
+
+ rule_ids = rule_pool.search(cr, uid, [('object_id', 'in', model_ids), ('state', '=', 'subscribed')])
+ if not rule_ids:
+ cr.close()
+ return super(audittrail_objects_proxy, self).exec_workflow(db, uid, model, method, *args, **argv)
+
+ for thisrule in rule_pool.browse(cr, uid, rule_ids):
+ for user in thisrule.user_id:
+ logged_uids.append(user.id)
+ if not logged_uids or uid in logged_uids:
+ if thisrule.log_workflow:
+ cr.close()
+ return self.log_fct(db, uid, model, method, fct_src, *args)
+ cr.close()
+ return super(audittrail_objects_proxy, self).exec_workflow(db, uid, model, method, *args, **argv)
+
+ cr.close()
+ return True
+
audittrail_objects_proxy()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/audittrail/audittrail_view.xml b/addons/audittrail/audittrail_view.xml
index a79e6a0b6c0..17b2594d470 100644
--- a/addons/audittrail/audittrail_view.xml
+++ b/addons/audittrail/audittrail_view.xml
@@ -12,12 +12,15 @@
-
+
@@ -83,13 +89,13 @@
-
-
-
+ action="action_audittrail_log_tree" parent="menu_action_audittrail" />
diff --git a/addons/audittrail/i18n/el.po b/addons/audittrail/i18n/el.po
index 6abb75f9b34..4b438a11d61 100644
--- a/addons/audittrail/i18n/el.po
+++ b/addons/audittrail/i18n/el.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2010-06-24 02:58+0000\n"
+"PO-Revision-Date: 2010-06-24 21:17+0000\n"
"Last-Translator: Panayiotis Konstantinidis \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: audittrail
@@ -159,153 +159,157 @@ msgid ""
" Subscribe Rules for read, write, create and delete on objects and check "
"logs"
msgstr ""
+"Επιστρέπει στον Διαχειριστή να ακολουθεί τα ίχνη κάθε λειτουργίας του χρήστη "
+"σε όλα τα αντικείμενα του συστήματος.\n"
+" Εισάγεται κανόνες για ανάγνωση, εγγραφή, δημιουργία και διαγραφή στα "
+"αντικείμενα και τα ημερολόγια ελέγχου."
#. module: audittrail
#: field:audittrail.log,timestamp:0
msgid "Date"
-msgstr ""
+msgstr "Ημερομηνία"
#. module: audittrail
#: field:audittrail.log,user_id:0
msgid "User"
-msgstr ""
+msgstr "Χρήστης"
#. module: audittrail
#: view:audittrail.log:0
msgid "Old Value Text : "
-msgstr ""
+msgstr "Παλιά τιμή κειμένου: "
#. module: audittrail
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Λανθασμένο XML για αρχιτεκτονική όψης!"
#. module: audittrail
#: field:audittrail.log,name:0
msgid "Name"
-msgstr ""
+msgstr "Όνομα"
#. module: audittrail
#: field:audittrail.log,line_ids:0
msgid "Log lines"
-msgstr ""
+msgstr "Γραμμές ημερολογίου"
#. module: audittrail
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_rule_tree_sub
msgid "Subscribed Rules"
-msgstr ""
+msgstr "Εγγεγραμμένοι Κανόνες"
#. module: audittrail
#: field:audittrail.log.line,field_id:0
msgid "Fields"
-msgstr ""
+msgstr "Πεδία"
#. module: audittrail
#: view:audittrail.rule:0
msgid "AuditTrail Rules"
-msgstr ""
+msgstr "Κανόνες διαδρομής ελέγχου"
#. module: audittrail
#: model:ir.model,name:audittrail.model_audittrail_rule
msgid "audittrail.rule"
-msgstr ""
+msgstr "ελεγκτική ιχνηλάτηση.κανόνες"
#. module: audittrail
#: view:audittrail.rule:0
msgid "UnSubscribe"
-msgstr ""
+msgstr "Διαγραφείτε"
#. module: audittrail
#: field:audittrail.rule,log_write:0
msgid "Log writes"
-msgstr ""
+msgstr "Εγγραφές ημερολογίου"
#. module: audittrail
#: model:ir.model,name:audittrail.model_audittrail_log
msgid "audittrail.log"
-msgstr ""
+msgstr "ελεγκτική ιχνηλάτηση.ημερολόγιο"
#. module: audittrail
#: field:audittrail.log.line,field_description:0
msgid "Field Description"
-msgstr ""
+msgstr "Περιγραφή πεδίου"
#. module: audittrail
#: selection:audittrail.log,method:0
msgid "Delete"
-msgstr ""
+msgstr "Διαγραφή"
#. module: audittrail
#: wizard_button:audittrail.view.log,init,open:0
msgid "Open Logs"
-msgstr ""
+msgstr "Άνοιγμα ημερολογίων"
#. module: audittrail
#: field:audittrail.log.line,new_value_text:0
msgid "New value Text"
-msgstr ""
+msgstr "Νέα τιμή κειμένου"
#. module: audittrail
#: field:audittrail.rule,name:0
msgid "Rule Name"
-msgstr ""
+msgstr "Όνομα Κανόνα"
#. module: audittrail
#: field:audittrail.rule,log_read:0
msgid "Log reads"
-msgstr ""
+msgstr "Αναγνώσεις ημερολογίων"
#. module: audittrail
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_log_tree
msgid "Logs"
-msgstr ""
+msgstr "Αρχεία καταγραφής"
#. module: audittrail
#: field:audittrail.log.line,new_value:0
msgid "New Value"
-msgstr ""
+msgstr "Νέα τιμή"
#. module: audittrail
#: model:ir.ui.menu,name:audittrail.menu_action_log_tree2
msgid "View Logs"
-msgstr ""
+msgstr "Δείτε τα αρχεία καταγραφής"
#. module: audittrail
#: field:audittrail.rule,log_create:0
msgid "Log creates"
-msgstr ""
+msgstr "Δημιουργία αρχείων καταγραφής"
#. module: audittrail
#: view:audittrail.log:0
msgid "AuditTrail Logs"
-msgstr ""
+msgstr "παρακολούθηση της πόρειας των αρχείων καταγραφής"
#. module: audittrail
#: model:ir.ui.menu,name:audittrail.menu_action_audittrail_rule_tree
msgid "Rules"
-msgstr ""
+msgstr "Κανόνες"
#. module: audittrail
#: view:audittrail.log:0
msgid "New Value : "
-msgstr ""
+msgstr "Νέα τιμή : "
#. module: audittrail
#: field:audittrail.rule,user_id:0
msgid "Users"
-msgstr ""
+msgstr "Χρήστες"
#. module: audittrail
#: field:audittrail.log.line,old_value_text:0
msgid "Old value Text"
-msgstr ""
+msgstr "Παλιά τιμή κειμένου"
#. module: audittrail
#: wizard_button:audittrail.view.log,init,end:0
msgid "Cancel"
-msgstr ""
+msgstr "Ακύρωση"
#. module: audittrail
#: field:audittrail.rule,log_unlink:0
msgid "Log deletes"
-msgstr ""
+msgstr "Διαγραφή αρχείων καταγραφής"
diff --git a/addons/base_action_rule/__openerp__.py b/addons/base_action_rule/__openerp__.py
index ab1ae6c965b..cdb62316d15 100644
--- a/addons/base_action_rule/__openerp__.py
+++ b/addons/base_action_rule/__openerp__.py
@@ -27,7 +27,9 @@
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base'],
- 'init_xml': [],
+ 'init_xml': [
+ 'base_action_rule_data.xml'
+ ],
'update_xml': [
'base_action_rule_view.xml',
'security/ir.model.access.csv',
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index a1213dd7542..8b9e6f700e8 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -19,14 +19,16 @@
#
##############################################################################
-import time
-import mx.DateTime
-import re
-
-import tools
+from datetime import datetime
from osv import fields, osv, orm
from osv.orm import except_orm
+from osv.osv import osv_pool
from tools.translate import _
+import mx.DateTime
+import pooler
+import re
+import time
+import tools
class base_action_rule(osv.osv):
""" Base Action Rules """
@@ -93,23 +95,23 @@ trigger date, like sending a reminder 15 minutes before a meeting."),
'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
'act_method': fields.char('Call Object Method', size=64),
- 'act_user_id': fields.many2one('res.users', 'Set responsible to'),
- 'act_state': fields.selection(_state_get, 'Set state to', size=16),
- 'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="\
+ 'act_user_id': fields.many2one('res.users', 'Set Responsible to'),
+ 'act_state': fields.selection(_state_get, 'Set State to', size=16),
+ 'act_email_cc': fields.char('Add Watchers (Cc)', size=250, help="\
These people will receive a copy of the future communication between partner \
and users by email"),
'act_remind_partner': fields.boolean('Remind Partner', help="Check \
this if you want the rule to send a reminder by email to the partner."),
- 'act_remind_user': fields.boolean('Remind responsible', help="Check \
+ 'act_remind_user': fields.boolean('Remind Responsible', help="Check \
this if you want the rule to send a reminder by email to the user."),
'act_reply_to': fields.char('Reply-To', size=64),
- 'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
- 'act_mail_to_user': fields.boolean('Mail to responsible', help="Check\
+ 'act_remind_attach': fields.boolean('Remind with Attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
+ 'act_mail_to_user': fields.boolean('Mail to Responsible', help="Check\
this if you want the rule to send an email to the responsible person."),
- 'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',
+ 'act_mail_to_watchers': fields.boolean('Mail to Watchers (CC)',
help="Check this if you want \
the rule to mark CC(mail to any other person defined in actions)."),
- 'act_mail_to_email': fields.char('Mail to these emails', size=128, \
+ 'act_mail_to_email': fields.char('Mail to these Emails', size=128, \
help="Email-id of the persons whom mail is to be sent"),
'act_mail_body': fields.text('Mail body', help="Content of mail"),
'regex_name': fields.char('Regular Expression on Model Name', size=128),
@@ -132,6 +134,71 @@ the rule to mark CC(mail to any other person defined in actions)."),
_order = 'sequence'
+ def pre_action(self, cr, uid, ids, model, context=None):
+ # Searching for action rules
+ cr.execute("SELECT model.model, rule.id FROM base_action_rule rule LEFT JOIN ir_model model on (model.id = rule.name)")
+ res = cr.fetchall()
+ # Check if any rule matching with current object
+ for obj_name, rule_id in res:
+ if not (model == obj_name):
+ continue
+ else:
+ obj = self.pool.get(obj_name)
+ self._action(cr, uid, [rule_id], obj.browse(cr, uid, ids, context=context))
+ return True
+
+ def _create(self, old_create, model, context=None):
+ if not context:
+ context = {}
+ def make_call_old(cr, uid, vals, context=context):
+ new_id = old_create(cr, uid, vals, context=context)
+ if not context.get('action'):
+ self.pre_action(cr, uid, [new_id], model, context=context)
+ return new_id
+ return make_call_old
+
+ def _write(self, old_write, model, context=None):
+ if not context:
+ context = {}
+ def make_call_old(cr, uid, ids, vals, context=context):
+ if isinstance(ids, (str, int, long)):
+ ids = [ids]
+ if not context.get('action'):
+ self.pre_action(cr, uid, ids, model, context=context)
+ return old_write(cr, uid, ids, vals, context=context)
+ return make_call_old
+
+ def _register_hook(self, cr, uid, ids, context=None):
+ if not context:
+ context = {}
+ model_pool = self.pool.get('ir.model')
+ for action_rule in self.browse(cr, uid, ids, context=context):
+ model = action_rule.name.model
+ obj_pool = self.pool.get(model)
+ obj_pool.__setattr__('create', self._create(obj_pool.create, model, context=context))
+ obj_pool.__setattr__('write', self._write(obj_pool.write, model, context=context))
+ return True
+
+ def create(self, cr, uid, vals, context=None):
+ res_id = super(base_action_rule, self).create(cr, uid, vals, context)
+ self._register_hook(cr, uid, [res_id], context=context)
+ return res_id
+
+ def write(self, cr, uid, ids, vals, context=None):
+ res = super(base_action_rule, self).write(cr, uid, ids, vals, context)
+ self._register_hook(cr, uid, ids, context=context)
+ return res
+
+ def _check(self, cr, uid, automatic=False, use_new_cursor=False, \
+ context=None):
+ """
+ This Function is call by scheduler.
+ """
+ rule_pool= self.pool.get('base.action.rule')
+ rule_ids = rule_pool.search(cr, uid, [], context=context)
+ return self._register_hook(cr, uid, rule_ids, context=context)
+
+
def format_body(self, body):
""" Foramat Action rule's body
@param self: The object pointer """
@@ -235,6 +302,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
context.update({'active_id':obj.id, 'active_ids':[obj.id]})
self.pool.get('ir.actions.server').run(cr, uid, [action.server_action_id.id], context)
write = {}
+
if hasattr(obj, 'user_id') and action.act_user_id:
obj.user_id = action.act_user_id
write['user_id'] = action.act_user_id.id
@@ -279,12 +347,10 @@ the rule to mark CC(mail to any other person defined in actions)."),
@param ids: List of Basic Action Rule’s IDs,
@param objects: pass objects
@param context: A standard dictionary for contextual values """
-
+ context.update({'action': True})
if not scrit:
scrit = []
- cr.execute("select id from base_action_rule order by sequence")
- rule_ids = map(lambda x: x[0], cr.fetchall())
- for action in self.browse(cr, uid, rule_ids):
+ for action in self.browse(cr, uid, ids):
level = action.max_level
if not level:
break
@@ -333,6 +399,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
self.do_action(cr, uid, action, model_obj, obj, context)
break
level -= 1
+ context.update({'action': False})
return True
def _check_mail(self, cr, uid, ids, context=None):
@@ -359,4 +426,27 @@ the rule to mark CC(mail to any other person defined in actions)."),
base_action_rule()
+
+class ir_cron(osv.osv):
+ _inherit = 'ir.cron'
+
+ def _poolJobs(self, db_name, check=False):
+ try:
+ db, pool = pooler.get_db_and_pool(db_name)
+ except:
+ return False
+ cr = db.cursor()
+ try:
+ next = datetime.now().strftime('%Y-%m-%d %H:00:00')
+ # Putting nextcall always less than current time in order to call it every time
+ cr.execute('UPDATE ir_cron set nextcall = \'%s\' where numbercall<>0 and active and model=\'base.action.rule\' ' % (next))
+ cr.commit()
+ res = super(ir_cron, self)._poolJobs(db_name, check=check)
+ finally:
+ cr.commit()
+ cr.close()
+
+ir_cron()
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_action_rule/base_action_rule_data.xml b/addons/base_action_rule/base_action_rule_data.xml
new file mode 100644
index 00000000000..288215202d6
--- /dev/null
+++ b/addons/base_action_rule/base_action_rule_data.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ Check Action Rules
+ 4
+ hours
+ -1
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml
index 0882b6f0e1b..4f502a4406b 100644
--- a/addons/base_action_rule/base_action_rule_view.xml
+++ b/addons/base_action_rule/base_action_rule_view.xml
@@ -18,7 +18,8 @@
-
+
+
@@ -54,7 +55,6 @@
-
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index 8a9764bff63..c16477280c7 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -377,6 +377,9 @@ property or property parameter."),
_defaults = {
'state': lambda *x: 'needs-action',
}
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ raise osv.except_osv(_('Warning!'), _('Can not Duplicate'))
def get_ics_file(self, cr, uid, event_obj, context=None):
"""
@@ -875,7 +878,7 @@ class calendar_event(osv.osv):
value = {
'duration': 24
}
- return {'value': value}
+ duration = 0.0
start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
if end_date and not duration:
@@ -1005,17 +1008,17 @@ class calendar_event(osv.osv):
_columns = {
'id': fields.integer('ID'),
'sequence': fields.integer('Sequence'),
- 'name': fields.char('Description', size=64, required=False),
- 'date': fields.datetime('Date'),
- 'date_deadline': fields.datetime('Deadline'),
+ 'name': fields.char('Description', size=64, required=False, states={'done': [('readonly', True)]}),
+ 'date': fields.datetime('Date', states={'done': [('readonly', True)]}),
+ 'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}),
'create_date': fields.datetime('Created', readonly=True),
- 'duration': fields.float('Duration'),
- 'description': fields.text('Your action'),
+ 'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
+ 'description': fields.text('Description', states={'done': [('readonly', True)]}),
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
- ('confidential', 'Confidential')], 'Mark as'),
- 'location': fields.char('Location', size=264, help="Location of Event"),
+ ('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
+ 'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
- 'Show as'),
+ 'Show as', states={'done': [('readonly', True)]}),
'base_calendar_url': fields.char('Caldav URL', size=264),
'exdate': fields.text('Exception Date/Times', help="This property \
defines the list of date/time exceptions for arecurring calendar component."),
@@ -1029,14 +1032,14 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=-1SU'),
'rrule_type': fields.selection([('none', ''), ('daily', 'Daily'), \
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
- ('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency'),
- 'alarm_id': fields.many2one('res.alarm', 'Alarm'),
+ ('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency', states={'done': [('readonly', True)]}),
+ 'alarm_id': fields.many2one('res.alarm', 'Alarm', states={'done': [('readonly', True)]}),
'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
'recurrent_uid': fields.integer('Recurrent ID'),
'recurrent_id': fields.datetime('Recurrent ID date'),
'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, \
string='Timezone', store=True),
- 'user_id': fields.many2one('res.users', 'Responsible'),
+ 'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
'freq': fields.selection([('None', 'No Repeat'), \
('secondly', 'Secondly'), \
('minutely', 'Minutely'), \
@@ -1068,7 +1071,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
'end_date': fields.date('Repeat Until'),
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
'event_id', 'attendee_id', 'Attendees'),
- 'allday': fields.boolean('All Day'),
+ 'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
'active': fields.boolean('Active', help="If the active field is set to \
true, it will allow you to hide the event alarm information without removing it.")
}
diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml
index 21b16443e0a..aa63dc696de 100644
--- a/addons/base_calendar/base_calendar_view.xml
+++ b/addons/base_calendar/base_calendar_view.xml
@@ -121,7 +121,7 @@
+ domain="[]" context="{'group_by':'state'}" />
@@ -138,7 +138,7 @@
+ parent="base.menu_base_config" sequence="15" />
diff --git a/addons/base_calendar/wizard/base_calendar_invite_attendee.py b/addons/base_calendar/wizard/base_calendar_invite_attendee.py
index cb3e4d2e62a..ebbfe6c48d2 100644
--- a/addons/base_calendar/wizard/base_calendar_invite_attendee.py
+++ b/addons/base_calendar/wizard/base_calendar_invite_attendee.py
@@ -65,7 +65,6 @@ send an Email to Invited Person')
context = {}
model = False
- model_field = False
context_id = context and context.get('active_id', False) or False
if not context or not context.get('model'):
return {}
diff --git a/addons/base_calendar/wizard/base_calendar_set_exrule.py b/addons/base_calendar/wizard/base_calendar_set_exrule.py
index ec7fcc50e9e..febfb39e1ef 100644
--- a/addons/base_calendar/wizard/base_calendar_set_exrule.py
+++ b/addons/base_calendar/wizard/base_calendar_set_exrule.py
@@ -104,11 +104,14 @@ class base_calendar_set_exrule(osv.osv_memory):
weekstring = ''
monthstring = ''
yearstring = ''
-
+ ex_id = base_calendar.base_calendar_id2real_id(context['active_id'])
+ model = context.get('model', False)
+ model_obj = self.pool.get(model)
for datas in self.read(cr, uid, ids, context=context):
freq = datas.get('freq')
if freq == 'None':
- return ''
+ model_obj.write(cr, uid, ex_id,{'exrule': ''})
+ return{}
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
@@ -143,12 +146,8 @@ class base_calendar_set_exrule(osv.osv_memory):
exrule_string = 'FREQ=' + freq.upper() + weekstring + interval_srting \
+ enddate + monthstring + yearstring
- ex_id = base_calendar.base_calendar_id2real_id(context['active_id'])
- model = context.get('model', False)
- model_obj = self.pool.get(model)
- exrule_value = model_obj.write(cr, uid,ex_id,{
- 'exrule': exrule_string,
- })
+
+ model_obj.write(cr, uid, ex_id,{'exrule': exrule_string})
return {}
_defaults = {
diff --git a/addons/base_calendar/wizard/base_calendar_set_exrule_view.xml b/addons/base_calendar/wizard/base_calendar_set_exrule_view.xml
index cc88dc90c02..bc663e0835f 100644
--- a/addons/base_calendar/wizard/base_calendar_set_exrule_view.xml
+++ b/addons/base_calendar/wizard/base_calendar_set_exrule_view.xml
@@ -49,11 +49,13 @@
attrs="{'required' : [('freq','=','yearly')]}"/>
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/addons/base_contact/__init__.py b/addons/base_contact/__init__.py
index 7cd056c1c20..84054cd59e7 100644
--- a/addons/base_contact/__init__.py
+++ b/addons/base_contact/__init__.py
@@ -20,5 +20,7 @@
##############################################################################
import base_contact
+import base_contact_installer
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_contact/__openerp__.py b/addons/base_contact/__openerp__.py
index a0fc97aa5a1..8c58d44ff4c 100644
--- a/addons/base_contact/__openerp__.py
+++ b/addons/base_contact/__openerp__.py
@@ -45,6 +45,7 @@
'update_xml': [
'security/ir.model.access.csv',
'base_contact_view.xml',
+ 'base_contact_installer_view.xml',
'process/base_contact_process.xml'
],
'demo_xml': ['base_contact_demo.xml'],
diff --git a/addons/base_contact/base_contact_installer.py b/addons/base_contact/base_contact_installer.py
new file mode 100644
index 00000000000..3cb32017111
--- /dev/null
+++ b/addons/base_contact/base_contact_installer.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from lxml import etree
+from osv import fields, osv
+
+class base_contact_installer(osv.osv_memory):
+ _name = 'base.contact.installer'
+ _inherit = 'res.config.installer'
+
+ _columns = {
+ 'name': fields.char('Name', size=64),
+ 'migrate': fields.boolean('Migrate', help="If you select this, all addresses will be migrated."),
+ }
+
+ def execute(self, cr, uid, ids, context=None):
+ """
+ This function is used to create contact and address from existing partner address
+ """
+ cr.execute("""DROP TRIGGER IF EXISTS contactjob on res_partner_contact;
+ DROP LANGUAGE IF EXISTS plpgsql CASCADE;
+ CREATE LANGUAGE plpgsql ;
+ CREATE OR REPLACE FUNCTION add_to_job() RETURNS TRIGGER AS $contactjob$
+ DECLARE
+ new_name varchar;
+ new_phonenum varchar;
+ BEGIN
+ IF(TG_OP='INSERT') THEN
+ INSERT INTO res_partner_job(contact_id, address_id, function, state) VALUES(NEW.id, NEW.website::integer,NEW.first_name, 'current');
+ UPDATE res_partner_contact set first_name=Null, website=Null, active=True where id=NEW.id;
+ END IF;
+ RETURN NEW;
+ END;
+ $contactjob$ LANGUAGE plpgsql;
+ CREATE TRIGGER contactjob AFTER INSERT ON res_partner_contact FOR EACH ROW EXECUTE PROCEDURE add_to_job();""")
+ cr.commit()
+
+ cr.execute("INSERT into res_partner_contact (name, title, email, first_name, website) (SELECT coalesce(name, 'Noname'), title, email, function , to_char(id, '99999999') from res_partner_address)")
+ cr.commit()
+
+ cr.execute("DROP TRIGGER IF EXISTS contactjob on res_partner_contact")
+ cr.execute("DROP LANGUAGE IF EXISTS plpgsql CASCADE;")
+ cr.execute("DROP FUNCTION IF EXISTS add_to_job()")
+ cr.commit()
+
+base_contact_installer()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_contact/base_contact_installer_view.xml b/addons/base_contact/base_contact_installer_view.xml
new file mode 100644
index 00000000000..3d93faa5728
--- /dev/null
+++ b/addons/base_contact/base_contact_installer_view.xml
@@ -0,0 +1,56 @@
+
+
+
+ base.contact.installer.view
+ base.contact.installer
+ form
+
+
+
+
+ Address's Migration to Contacts
+
+
+
+ Select the Option for Addresses Migration
+
+
+ You can migrate Partner's current addresses to the contact.
+
+
+ 13
+
+
+
+ Migrate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Address Migration
+ ir.actions.act_window
+ base.contact.installer
+
+ form
+ form
+ new
+
+
+
+
+ 3
+
+
+
+
diff --git a/addons/base_module_quality/i18n/el.po b/addons/base_module_quality/i18n/el.po
index 9ae13c3add3..4472efd47d4 100644
--- a/addons/base_module_quality/i18n/el.po
+++ b/addons/base_module_quality/i18n/el.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_module_quality
diff --git a/addons/base_module_quality/i18n/es.po b/addons/base_module_quality/i18n/es.po
index fbb4ecf48fb..fadb0ecd58e 100644
--- a/addons/base_module_quality/i18n/es.po
+++ b/addons/base_module_quality/i18n/es.po
@@ -15,7 +15,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_module_quality
diff --git a/addons/base_module_quality/pep8_test/pep8_test.py b/addons/base_module_quality/pep8_test/pep8_test.py
index 52c04756382..4aaaaa7bddc 100644
--- a/addons/base_module_quality/pep8_test/pep8_test.py
+++ b/addons/base_module_quality/pep8_test/pep8_test.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
##############################################################################
@@ -48,7 +48,7 @@ PEP-8 Test , copyright of py files check, method can not call from loops
list_files.append(os.path.join(i, j))
py_list = []
for file_py in list_files:
- if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__terp__.py'):
+ if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__openerp__.py'):
file_path = os.path.join(module_path, file_py)
py_list.append(file_path)
diff --git a/addons/base_module_quality/pylint_test/pylint_test.py b/addons/base_module_quality/pylint_test/pylint_test.py
index 8dbbce0e2ce..12400dbb196 100644
--- a/addons/base_module_quality/pylint_test/pylint_test.py
+++ b/addons/base_module_quality/pylint_test/pylint_test.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
##############################################################################
@@ -50,7 +50,7 @@ class quality_test(base_module_quality.abstract_quality_check):
flag = False
self.result_details += '''%s'''%(self.get_style())
for file_py in list_files:
- if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__terp__.py'):
+ if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__openerp__.py'):
if not flag:
flag = True
file_path = os.path.join(module_path, file_py)
diff --git a/addons/base_module_quality/structure_test/structure_test.py b/addons/base_module_quality/structure_test/structure_test.py
index 466976f5d17..10b80aaacdd 100644
--- a/addons/base_module_quality/structure_test/structure_test.py
+++ b/addons/base_module_quality/structure_test/structure_test.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
##############################################################################
@@ -82,7 +82,7 @@ This test checks if the module satisfy tiny structure
# module files calculation (module.py,module_view.xml,etc..)
com_list = ['_unit_test.xml', '.py', '_view.xml', '_workflow.xml' , '_wizard.xml', '_report.xml', '_data.xml', '_demo.xml', '_security.xml', '_sequence.xml', '_graph.xml']
com_list = map(lambda x: module_name + x, com_list)
- main_file = ['__init__.py', '__terp__.py']
+ main_file = ['__init__.py', '__openerp__.py']
com_list.extend(main_file)
module_dict['module'] = filter(lambda x: len(x.split(".")) > 1, module_dict['module'])
score = self.get_score(module_dict['module'], com_list)
diff --git a/addons/base_module_quality/terp_test/terp_test.py b/addons/base_module_quality/terp_test/terp_test.py
index 993a80fe32b..b2d71b9fbd9 100644
--- a/addons/base_module_quality/terp_test/terp_test.py
+++ b/addons/base_module_quality/terp_test/terp_test.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
##############################################################################
@@ -49,13 +49,13 @@ class quality_test(base_module_quality.abstract_quality_check):
score = 1.0
feel_good_factor = 0
feel_bad_factor = 0
- if '__terp__.py' not in list_files:
+ if '__openerp__.py' not in list_files:
self.no_terp = True
- self.result += _("The module does not contain the __terp__.py file")
+ self.result += _("The module does not contain the __openerp__.py file")
return None
result_dict = {}
result_dict1 = {}
- terp_file = os.path.join(module_path,'__terp__.py')
+ terp_file = os.path.join(module_path,'__openerp__.py')
res = eval(tools.file_open(terp_file).read())
terp_keys = ['category', 'name', 'description', 'author', 'website', 'update_xml', 'init_xml', 'depends', 'version', 'active', 'installable', 'demo_xml']
for key in terp_keys:
@@ -117,7 +117,7 @@ class quality_test(base_module_quality.abstract_quality_check):
self.result_details += self.get_result_details(result_dict)
self.result_details += self.get_result_details(result_dict1)
- return [_('__terp__.py file'), score]
+ return [_('__openerp__.py file'), score]
def run_test(self, cr, uid, module_path):
terp_score = self.run_test_terp(cr, uid, module_path)
@@ -125,7 +125,7 @@ class quality_test(base_module_quality.abstract_quality_check):
if self.score*100 < self.min_score:
self.message = 'Score is below than minimal score(%s%%)' % self.min_score
if terp_score:
- self.result = self.get_result({'__terp__.py': terp_score})
+ self.result = self.get_result({'__openerp__.py': terp_score})
return None
def get_result(self, dict_terp):
@@ -144,4 +144,4 @@ class quality_test(base_module_quality.abstract_quality_check):
return res
return ""
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_report_creator/i18n/el.po b/addons/base_report_creator/i18n/el.po
index a914194a57b..7efe97b103a 100644
--- a/addons/base_report_creator/i18n/el.po
+++ b/addons/base_report_creator/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/board_association/i18n/el.po b/addons/board_association/i18n/el.po
index 35fcc48ad27..9ef871e24af 100644
--- a/addons/board_association/i18n/el.po
+++ b/addons/board_association/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/board_auction/i18n/el.po b/addons/board_auction/i18n/el.po
index f99a794521e..990647cd866 100644
--- a/addons/board_auction/i18n/el.po
+++ b/addons/board_auction/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/board_crm_configuration/i18n/el.po b/addons/board_crm_configuration/i18n/el.po
index e2f697e23fd..93c5529b516 100644
--- a/addons/board_crm_configuration/i18n/el.po
+++ b/addons/board_crm_configuration/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/board_document/i18n/el.po b/addons/board_document/i18n/el.po
index 338203acd35..e3ccc369296 100644
--- a/addons/board_document/i18n/el.po
+++ b/addons/board_document/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/board_project/i18n/el.po b/addons/board_project/i18n/el.po
index 4b6cc7b8820..cc09dff76e2 100644
--- a/addons/board_project/i18n/el.po
+++ b/addons/board_project/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/caldav/wizard/calendar_event_export.py b/addons/caldav/wizard/calendar_event_export.py
index 856d9e9bc91..0be54df9f56 100644
--- a/addons/caldav/wizard/calendar_event_export.py
+++ b/addons/caldav/wizard/calendar_event_export.py
@@ -32,16 +32,6 @@ class calendar_event_export(osv.osv_memory):
"""
Export Calendar Event.
"""
- def process_export_ics(self, cr, uid, ids, context):
- """
- Get Default value for file_path field.
- """
- model = context.get('model', 'basic.calendar')
- model_obj = self.pool.get(model)
-
- calendar = model_obj.export_cal(cr, uid, context['active_ids'], context)
- self.write(cr, uid, ids, {'file_path': base64.encodestring(calendar)})
- return False
def default_get(self, cr, uid, fields, context):
"""
@@ -54,6 +44,9 @@ class calendar_event_export(osv.osv_memory):
name = 'OpenERP %s.ics' % (model_obj._description)
if 'name' in fields:
res.update({'name': name})
+ if 'file_path' in fields:
+ calendar = model_obj.export_cal(cr, uid, context['active_ids'], context)
+ res.update({'file_path': base64.encodestring(calendar)})
return res
_name = "calendar.event.export"
diff --git a/addons/caldav/wizard/calendar_event_export_view.xml b/addons/caldav/wizard/calendar_event_export_view.xml
index 227822966d0..cfadf945bf4 100644
--- a/addons/caldav/wizard/calendar_event_export_view.xml
+++ b/addons/caldav/wizard/calendar_event_export_view.xml
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/addons/crm/__init__.py b/addons/crm/__init__.py
index 362444ccc2c..e56ed80af30 100644
--- a/addons/crm/__init__.py
+++ b/addons/crm/__init__.py
@@ -20,7 +20,6 @@
##############################################################################
import crm
-import crm_mailgate
import crm_action_rule
import crm_segmentation
import crm_meeting
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index 5dcb655e8db..6e7a8edb807 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -69,7 +69,6 @@ Create dashboard for CRM that includes:
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
-
'update_xml': [
'wizard/crm_lead_to_partner_view.xml',
'wizard/crm_lead_to_opportunity_view.xml',
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 7510bc48914..feb49ba7ae7 100644
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -121,11 +121,16 @@ class crm_case(object):
s = self.get_stage_dict(cr, uid, ids, context=context)
section = self._name
+ stage_pool = self.pool.get('crm.case.stage')
for case in self.browse(cr, uid, ids, context):
if section in s:
st = case.stage_id.id or False
if st in s[section]:
- self.write(cr, uid, [case.id], {'stage_id': s[section][st]})
+ data = {'stage_id': s[section][st]}
+ stage = stage_pool.browse(cr, uid, s[section][st], context=context)
+ if stage.on_change:
+ data.update({'probability': stage.probability})
+ self.write(cr, uid, [case.id], data)
return True
def get_stage_dict(self, cr, uid, ids, context=None):
@@ -162,12 +167,17 @@ class crm_case(object):
s = self.get_stage_dict(cr, uid, ids, context=context)
section = self._name
+ stage_pool = self.pool.get('crm.case.stage')
for case in self.browse(cr, uid, ids, context):
if section in s:
st = case.stage_id.id or False
s[section] = dict([(v, k) for (k, v) in s[section].iteritems()])
if st in s[section]:
- self.write(cr, uid, [case.id], {'stage_id': s[section][st]})
+ data = {'stage_id': s[section][st]}
+ stage = stage_pool.browse(cr, uid, s[section][st], context=context)
+ if stage.on_change:
+ data.update({'probability': stage.probability})
+ self.write(cr, uid, [case.id], data)
return True
def onchange_partner_id(self, cr, uid, ids, part, email=False):
@@ -181,7 +191,8 @@ class crm_case(object):
"""
if not part:
return {'value': {'partner_address_id': False,
- 'email_from': False,
+ 'email_from': False,
+ 'phone': False
}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
data = {'partner_address_id': addr['contact']}
@@ -200,7 +211,7 @@ class crm_case(object):
if not add:
return {'value': {'email_from': False}}
address = self.pool.get('res.partner.address').browse(cr, uid, add)
- return {'value': {'email_from': address.email}}
+ return {'value': {'email_from': address.email, 'phone': address.phone}}
def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context={}):
mailgate_pool = self.pool.get('mailgate.thread')
@@ -541,7 +552,7 @@ class crm_case_resource_type(osv.osv):
_rec_name = "name"
_columns = {
- 'name': fields.char('Case Resource Type', size=64, required=True, translate=True),
+ 'name': fields.char('Resource Type', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml
index 1873f53f573..e8d5965a4c0 100644
--- a/addons/crm/crm_data.xml
+++ b/addons/crm/crm_data.xml
@@ -5,18 +5,5 @@
Sales Department
Sales
-
-
-
- Check cases rules
- 4
- hours
- -1
-
-
-
-
-
-
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index c1060f3e658..2700581d6cc 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -27,15 +27,16 @@ import time
import mx.DateTime
from tools.translate import _
from crm import crm_case
+import collections
+import binascii
+import tools
class crm_lead(osv.osv, crm_case):
""" CRM Lead Case """
-
_name = "crm.lead"
_description = "Lead"
_order = "priority, id desc"
- _inherit = ['res.partner.address']
- _inherits = {'mailgate.thread': 'thread_id'}
+ _inherit = ['mailgate.thread','res.partner.address']
def _compute_day(self, cr, uid, ids, fields, args, context={}):
"""
@@ -112,7 +113,6 @@ and users by email"),
'write_date': fields.datetime('Update Date' , readonly=True),
# Lead fields
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'categ_id': fields.many2one('crm.case.categ', 'Lead Source', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.lead')]"),
@@ -120,6 +120,8 @@ and users by email"),
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.lead')]"),
'partner_name': fields.char("Partner Name", size=64),
+ 'optin': fields.selection([('yes','Yes'),('no','No'),('unknown','/')],'Opt-In'),
+ 'optout': fields.selection([('yes','Yes'),('no','No'),('unknown','/')],'Opt-Out'),
'type':fields.selection([
('lead','Lead'),
('opportunity','Opportunity'),
@@ -142,6 +144,8 @@ and users by email"),
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
}
_defaults = {
@@ -149,6 +153,8 @@ and users by email"),
'user_id': crm_case._get_default_user,
'email_from': crm_case._get_default_email,
'state': lambda *a: 'draft',
+ 'optin': lambda *a: 'unknown',
+ 'optout': lambda *a: 'unknown',
'section_id': crm_case._get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
@@ -232,6 +238,130 @@ and users by email"),
}
return value
+ def message_new(self, cr, uid, msg, context):
+ """
+ Automatically calls when new email message arrives
+
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks
+ """
+
+ mailgate_pool = self.pool.get('email.server.tools')
+
+ subject = msg.get('subject')
+ body = msg.get('body')
+ msg_from = msg.get('from')
+ priority = msg.get('priority')
+
+ vals = {
+ 'name': subject,
+ 'email_from': msg_from,
+ 'email_cc': msg.get('cc'),
+ 'description': body,
+ 'user_id': False,
+ }
+ if msg.get('priority', False):
+ vals['priority'] = priority
+
+ res = mailgate_pool.get_partner(cr, uid, msg.get('from'))
+ if res:
+ vals.update(res)
+ res = self.create(cr, uid, vals, context)
+
+
+ attachents = msg.get('attachments', [])
+ for attactment in attachents or []:
+ data_attach = {
+ 'name': attactment,
+ 'datas':binascii.b2a_base64(str(attachents.get(attactment))),
+ 'datas_fname': attactment,
+ 'description': 'Mail attachment',
+ 'res_model': self._name,
+ 'res_id': res,
+ }
+ self.pool.get('ir.attachment').create(cr, uid, data_attach)
+
+ return res
+
+ def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context={}):
+ """
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of update mail’s IDs
+ """
+
+ if isinstance(ids, (str, int, long)):
+ ids = [ids]
+
+ msg_from = msg['from']
+ vals.update({
+ 'description': msg['body']
+ })
+ if msg.get('priority', False):
+ vals['priority'] = msg.get('priority')
+
+ maps = {
+ 'cost':'planned_cost',
+ 'revenue': 'planned_revenue',
+ 'probability':'probability'
+ }
+ vls = { }
+ for line in msg['body'].split('\n'):
+ line = line.strip()
+ res = tools.misc.command_re.match(line)
+ if res and maps.get(res.group(1).lower(), False):
+ key = maps.get(res.group(1).lower())
+ vls[key] = res.group(2).lower()
+
+ vals.update(vls)
+ res = self.write(cr, uid, ids, vals)
+ return res
+
+ def emails_get(self, cr, uid, ids, context=None):
+
+ """
+ Get Emails
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of email’s IDs
+ @param context: A standard dictionary for contextual values
+ """
+ res = {}
+
+ if isinstance(ids, (str, int, long)):
+ select = [long(ids)]
+ else:
+ select = ids
+
+ for thread in self.browse(cr, uid, select, context=context):
+ values = collections.defaultdict(set)
+
+ for message in thread.message_ids:
+ user_email = (message.user_id and message.user_id.address_id and message.user_id.address_id.email) or False
+ values['user_email'].add(user_email)
+ values['email_from'].add(message.email_from)
+ values['email_cc'].add(message.email_cc or False)
+ values['priority'] = thread.priority
+
+ res[thread.id] = dict((key,list(values[key])) for key, value in values.iteritems())
+
+ return res
+
+ def msg_send(self, cr, uid, id, *args, **argv):
+
+ """ Send The Message
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of email’s IDs
+ @param *args: Return Tuple Value
+ @param **args: Return Dictionary of Keyword Value
+ """
+ return True
+
crm_lead()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index c33339047d8..0c5afb27739 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -146,6 +146,11 @@
+
+
+
+
+
@@ -256,12 +261,11 @@
calendar
-
+
-
+
diff --git a/addons/crm/crm_mailgate.py b/addons/crm/crm_mailgate.py
deleted file mode 100644
index f2380182aad..00000000000
--- a/addons/crm/crm_mailgate.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-import time
-import re
-import os
-
-import binascii
-import mx.DateTime
-import base64
-
-from tools.translate import _
-
-import tools
-from osv import fields,osv,orm
-from osv.orm import except_orm
-import collections
-
-from tools import command_re
-
-class mailgate_thread(osv.osv):
- """ mailgate_thread """
-
- _name = "mailgate.thread"
- _inherit = "mailgate.thread"
-
- def message_new(self, cr, uid, msg, context):
- """
- Automatically calls when new email message arrives
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks
- """
-
- mailgate_pool = self.pool.get('email.server.tools')
-
- subject = msg.get('subject')
- body = msg.get('body')
- msg_from = msg.get('from')
- priority = msg.get('priority')
-
- vals = {
- 'name': subject,
- 'email_from': msg_from,
- 'email_cc': msg.get('cc'),
- 'description': body,
- 'user_id': False,
- }
- if msg.get('priority', False):
- vals['priority'] = priority
-
- res = mailgate_pool.get_partner(cr, uid, msg.get('from'))
- if res:
- vals.update(res)
- res = self.create(cr, uid, vals, context)
- cases = self.browse(cr, uid, [res])
- self._history(cr, uid, cases, _('Receive'), history=True, details=body, email_from=msg_from, message_id=msg.get('id'))
-
- attachents = msg.get('attachments', [])
- for attactment in attachents or []:
- data_attach = {
- 'name': attactment,
- 'datas':binascii.b2a_base64(str(attachents.get(attactment))),
- 'datas_fname': attactment,
- 'description': 'Mail attachment',
- 'res_model': self._name,
- 'res_id': res,
- }
- self.pool.get('ir.attachment').create(cr, uid, data_attach)
-
- return res
-
- def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context={}):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of update mail’s IDs
- """
-
- if isinstance(ids, (str, int, long)):
- ids = [ids]
-
- msg_from = msg['from']
- vals.update({
- 'description': msg['body']
- })
- if msg.get('priority', False):
- vals['priority'] = msg.get('priority')
-
- maps = {
- 'cost':'planned_cost',
- 'revenue': 'planned_revenue',
- 'probability':'probability'
- }
- vls = { }
- for line in msg['body'].split('\n'):
- line = line.strip()
- res = command_re.match(line)
- if res and maps.get(res.group(1).lower(), False):
- key = maps.get(res.group(1).lower())
- vls[key] = res.group(2).lower()
-
- vals.update(vls)
- res = self.write(cr, uid, ids, vals)
- cases = self.browse(cr, uid, ids)
- message_id = context.get('references_id', False)
- self._history(cr, uid, cases, _('Receive'), history=True, details=msg['body'], email_from=msg_from, message_id=message_id)
- #getattr(self, act)(cr, uid, select)
- return res
-
- def emails_get(self, cr, uid, ids, context=None):
-
- """
- Get Emails
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of email’s IDs
- @param context: A standard dictionary for contextual values
- """
- res = {}
-
- if isinstance(ids, (str, int, long)):
- select = [long(ids)]
- else:
- select = ids
-
- for thread in self.browse(cr, uid, select, context=context):
- values = collections.defaultdict(set)
-
- for message in thread.message_ids:
- user_email = (message.user_id and message.user_id.address_id and message.user_id.address_id.email) or False
- values['user_email'].add(user_email)
- values['email_from'].add(message.email_from)
- values['email_cc'].add(message.email_cc or False)
-
- res[str(thread.id)] = dict((key,list(values[key])) for key, value in values.iteritems())
-
- return res
-
- def msg_send(self, cr, uid, id, *args, **argv):
-
- """ Send The Message
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of email’s IDs
- @param *args: Return Tuple Value
- @param **args: Return Dictionary of Keyword Value
- """
- return True
-
-mailgate_thread()
diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py
index e45ee85b31d..4f68d2d2564 100644
--- a/addons/crm/crm_meeting.py
+++ b/addons/crm/crm_meeting.py
@@ -43,32 +43,32 @@ class crm_meeting(osv.osv, crm_case):
_name = 'crm.meeting'
_description = "Meeting"
_order = "id desc"
- _inherit = ["calendar.event"]
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread',"calendar.event"]
_columns = {
# From crm.case
- 'name': fields.char('Summary', size=124, required=True),
- 'partner_id': fields.many2one('res.partner', 'Partner'),
+ 'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
+ 'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
- domain="[('partner_id','=',partner_id)]"),
- 'section_id': fields.many2one('crm.case.section', 'Sales Team', \
+ domain="[('partner_id','=',partner_id)]", states={'done': [('readonly', True)]}),
+ 'section_id': fields.many2one('crm.case.section', 'Sales Team', states={'done': [('readonly', True)]}, \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),
- 'email_from': fields.char('Email', size=128, help="These people will receive email."),
+ 'email_from': fields.char('Email', size=128, states={'done': [('readonly', True)]}, help="These people will receive email."),
'id': fields.integer('ID'),
-
+ 'create_date': fields.datetime('Creation Date' , readonly=True),
+ 'write_date': fields.datetime('Write Date' , readonly=True),
# Meeting fields
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'categ_id': fields.many2one('crm.case.categ', 'Meeting Type', \
domain="[('object_id.model', '=', 'crm.meeting')]", \
),
'phonecall_id': fields.many2one ('crm.phonecall', 'Phonecall'),
'opportunity_id': fields.many2one ('crm.lead', 'Opportunity', domain="[('type', '=', 'opportunity')]"),
'attendee_ids': fields.many2many('calendar.attendee', 'meeting_attendee_rel',\
- 'event_id', 'attendee_id', 'Attendees'),
+ 'event_id', 'attendee_id', 'Attendees', states={'done': [('readonly', True)]}),
'date_closed': fields.datetime('Closed', readonly=True),
- 'date_deadline': fields.datetime('Deadline'),
+ 'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
'state': fields.selection([('open', 'Confirmed'),
('draft', 'Unconfirmed'),
('cancel', 'Cancelled'),
diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml
index 34bdafe1c58..5d1bb3f29d7 100644
--- a/addons/crm/crm_meeting_view.xml
+++ b/addons/crm/crm_meeting_view.xml
@@ -148,6 +148,7 @@
@@ -214,10 +215,27 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -268,6 +286,10 @@
help="Current Meetings"/>
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_opportunity.py b/addons/crm/crm_opportunity.py
index 440033a2400..0adbf2f2489 100644
--- a/addons/crm/crm_opportunity.py
+++ b/addons/crm/crm_opportunity.py
@@ -143,9 +143,10 @@ class crm_opportunity(osv.osv):
context = {
'default_opportunity_id': opp.id,
'default_partner_id': opp.partner_id and opp.partner_id.id or False,
+ 'default_user_id': uid,
'default_section_id': opp.section_id and opp.section_id.id or False,
'default_email_from': opp.email_from,
- 'default_state': 'open',
+ 'default_state': 'open',
'default_name': opp.name
}
value = {
diff --git a/addons/crm/crm_opportunity_menu.xml b/addons/crm/crm_opportunity_menu.xml
index cb24990416f..36163abfa00 100644
--- a/addons/crm/crm_opportunity_menu.xml
+++ b/addons/crm/crm_opportunity_menu.xml
@@ -7,9 +7,9 @@
name="Phone calls"
res_model="crm.phonecall"
src_model="crm.lead"
- view_mode="calendar,tree,form"
+ view_mode="tree,calendar,form"
context="{'default_duration': 1.0 ,'default_opportunity_id': active_id}"
- domain="[('user_id','=',uid),('opportunity_id', '=', active_id)]"
+ domain="[('opportunity_id', '=', active_id)]"
view_type="form"/>
diff --git a/addons/crm/crm_opportunity_view.xml b/addons/crm/crm_opportunity_view.xml
index 550d82f86ac..4060337bdd7 100644
--- a/addons/crm/crm_opportunity_view.xml
+++ b/addons/crm/crm_opportunity_view.xml
@@ -258,6 +258,8 @@
+
+
-
+
diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py
index 657360a4206..1d6a855c208 100644
--- a/addons/crm/crm_phonecall.py
+++ b/addons/crm/crm_phonecall.py
@@ -31,13 +31,11 @@ class crm_phonecall(osv.osv, crm_case):
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread']
_columns = {
# From crm.case
'name': fields.char('Name', size=64),
'active': fields.boolean('Active', required=False),
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'create_date': fields.datetime('Creation Date' , readonly=True),
@@ -84,6 +82,8 @@ class crm_phonecall(osv.osv, crm_case):
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Opportunity'),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
}
_defaults = {
diff --git a/addons/crm/crm_phonecall_demo.xml b/addons/crm/crm_phonecall_demo.xml
index 571848c54c7..824c40454be 100644
--- a/addons/crm/crm_phonecall_demo.xml
+++ b/addons/crm/crm_phonecall_demo.xml
@@ -18,6 +18,7 @@
+
@@ -33,6 +34,7 @@
+
@@ -49,6 +51,7 @@
+
@@ -63,6 +66,7 @@
+
@@ -78,6 +82,7 @@
+
@@ -94,6 +99,7 @@
+
diff --git a/addons/crm/crm_phonecall_menu.xml b/addons/crm/crm_phonecall_menu.xml
index 74bba86be04..f1363456e2c 100644
--- a/addons/crm/crm_phonecall_menu.xml
+++ b/addons/crm/crm_phonecall_menu.xml
@@ -12,6 +12,16 @@
domain="[('partner_id', '=', active_id)]"
groups="base.group_extended"
/>
+
+
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 59b8013b167..790debb007f 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -118,9 +118,6 @@
-
@@ -132,6 +129,9 @@
+
@@ -146,8 +146,8 @@
-
-
+
+
-
-
@@ -212,6 +210,7 @@
+
-
+
-
+
-
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
diff --git a/addons/crm/report/crm_lead_report.py b/addons/crm/report/crm_lead_report.py
index db9837b5d0c..a70bd45875d 100644
--- a/addons/crm/report/crm_lead_report.py
+++ b/addons/crm/report/crm_lead_report.py
@@ -109,7 +109,6 @@ class crm_lead_report(osv.osv):
'date_closed': fields.date('Close Date', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
-
'type':fields.selection([
('lead','Lead'),
('opportunity','Opportunity'),
@@ -148,7 +147,7 @@ class crm_lead_report(osv.osv):
0 as avg_answers,
0.0 as perc_done,
0.0 as perc_cancel,
- (select count(id) from mailgate_message where thread_id=c.id) as email,
+ (select count(id) from mailgate_message where res_id=c.id and model='crm.lead') as email,
date_trunc('day',c.create_date) as create_date,
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close,
avg(extract('epoch' from (c.date_deadline - c.date_closed)))/(3600*24) as delay_expected,
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index 8befbd8c084..595e63736bf 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -30,9 +30,8 @@
"access_crm_lead2opportunity_partner","crm.lead2opportunity.partner","model_crm_lead2opportunity_partner","crm.group_crm_user",1,1,1,1
"access_crm_installer","crm.installer.rule","model_crm_installer","base.group_system",1,1,1,1
"access_crm_lead_forward_to_partner","crm.lead.forward.to.partner","model_crm_lead_forward_to_partner","crm.group_crm_user",1,1,1,1
-"access_mailgate_thread","mailgate.thread","model_mailgate_thread","crm.group_crm_user",1,1,1,1
"access_res_partner","res.partner.crm.user","base.model_res_partner","crm.group_crm_user",1,0,0,0
"access_res_partner_address","res.partner.address.crm.user","base.model_res_partner_address","crm.group_crm_user",1,0,0,0
"access_res_partner_category","res.partner.category.crm.user","base.model_res_partner_category","crm.group_crm_user",1,0,0,0
"mail_gateway_mailgate_message","mail_gateway.mailgate.message","mail_gateway.model_mailgate_message","crm.group_crm_user",1,1,1,1
-"mail_gateway_mailgate_thread","mail_gateway.mailgate.thread","model_mailgate_thread","crm.group_crm_user",1,1,1,1
+"mail_gateway_mailgate_thread","mail_gateway.mailgate.thread","mail_gateway.model_mailgate_thread","crm.group_crm_user",1,1,1,1
diff --git a/addons/crm/wizard/crm_forward_to_partner.py b/addons/crm/wizard/crm_forward_to_partner.py
index 945066506d7..afae01ca2fe 100644
--- a/addons/crm/wizard/crm_forward_to_partner.py
+++ b/addons/crm/wizard/crm_forward_to_partner.py
@@ -183,25 +183,18 @@ class crm_lead_forward_to_partner(osv.osv_memory):
emails = [this.email_to]
body = case_pool.format_body(this.message)
email_from = this.email_from or False
- case_pool._history(cr, uid, [case], _('Forward'), history=True, email=this.email_to, details=body, email_from=email_from)
flag = False
- if case.section_id and case.section_id.server_id:
- flag = smtp_pool.send_email(
- cr=cr,
- uid=uid,
- server_id=case.section_id.server_id.id,
- emailto=emails,
- subject=this.subject,
- body="%s " % body,
- )
- else:
- flag = tools.email_send(
- email_from,
- emails,
- this.subject,
- body,
- )
+ flag = tools.email_send(
+ email_from,
+ emails,
+ this.subject,
+ body,
+ )
+ if flag:
+ case_pool._history(cr, uid, [case], _('Forward'), history=True, email=this.email_to, subject=this.subject, details=body, email_from=email_from)
+ if not flag:
+ raise osv.except_osv(_('Error!'), _('Unable to send mail. Please check SMTP is configured properly.'))
if this.add_cc:
case_pool.write(cr, uid, case.id, {'email_cc' : case.email_cc and case.email_cc + ', ' + this.email_to or this.email_to})
return {}
@@ -210,7 +203,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
message = []
lead_proxy = self.pool.get('crm.lead')
lead = lead_proxy.browse(cr, uid, lead_id, context=context)
- if lead.type == 'lead':
+ if not lead.type or lead.type == 'lead':
field_names = [
'partner_name', 'title', 'function', 'street', 'street2',
'zip', 'city', 'country_id', 'state_id', 'email_from',
diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml
index 827ee867169..da8db534812 100644
--- a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml
@@ -9,13 +9,15 @@
crm.opportunity2phonecall
form
-
+
+
+
diff --git a/addons/crm/wizard/crm_phonecall_to_opportunity.py b/addons/crm/wizard/crm_phonecall_to_opportunity.py
index 453a4098926..f24d5379997 100644
--- a/addons/crm/wizard/crm_phonecall_to_opportunity.py
+++ b/addons/crm/wizard/crm_phonecall_to_opportunity.py
@@ -85,11 +85,19 @@ Call Could not convert into Opportunity"))
id3 = data_obj.browse(cr, uid, id3, context=context).res_id
for this in self.browse(cr, uid, ids, context=context):
+ address = None
+ if this.partner_id:
+ address_id = self.pool.get('res.partner').address_get(cr, uid, [this.partner_id.id])
+ if address_id:
+ address = self.pool.get('res.partner.address').browse(cr, uid, address_id['default'], context=context)
new_opportunity_id = opp_obj.create(cr, uid, {
'name': this.name,
'planned_revenue': this.planned_revenue,
'probability': this.probability,
'partner_id': this.partner_id and this.partner_id.id or False,
+ 'partner_address_id': address and address.id,
+ 'phone': address and address.phone,
+ 'mobile': address and address.mobile,
'section_id': case.section_id and case.section_id.id or False,
'description': case.description or False,
'phonecall_id': case.id,
diff --git a/addons/crm/wizard/crm_phonecall_to_phonecall.py b/addons/crm/wizard/crm_phonecall_to_phonecall.py
index 9b9464eea3d..d22e70303d7 100644
--- a/addons/crm/wizard/crm_phonecall_to_phonecall.py
+++ b/addons/crm/wizard/crm_phonecall_to_phonecall.py
@@ -94,6 +94,7 @@ class crm_phonecall2phonecall(osv.osv_memory):
'views': [(id2, 'form'), (id3, 'tree'), (False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'res_id': phonecall_id,
+ 'domain': [('id', 'in', [int(phonecall_id)])],
'search_view_id': res['res_id']
}
return res
diff --git a/addons/crm/wizard/crm_send_email.py b/addons/crm/wizard/crm_send_email.py
index 3588371984b..480ea0f10a1 100644
--- a/addons/crm/wizard/crm_send_email.py
+++ b/addons/crm/wizard/crm_send_email.py
@@ -23,6 +23,7 @@
from osv import osv, fields
from tools.translate import _
import base64
+import time
import tools
from crm import crm
@@ -96,27 +97,23 @@ class crm_send_new_email(osv.osv_memory):
else:
hist = hist_obj.browse(cr, uid, res_id)
message_id = hist.message_id
- model = hist.model_id.model
+ model = hist.model
model_pool = self.pool.get(model)
res_ids = model_pool.search(cr, uid, [('thread_id','=', hist.thread_id.id)])
res_id = res_ids and res_ids[0] or False
case = model_pool.browse(cr, uid, res_id)
- emails = [obj.email_to] + (obj.email_cc or '').split(',')
+ emails = [obj.email_to]
+ email_cc = (obj.email_cc or '').split(',')
emails = filter(None, emails)
body = obj.text
body = case_pool.format_body(body)
email_from = getattr(obj, 'email_from', False)
- case_pool._history(cr, uid, [case], _('Send'), history=True, \
- email=obj.email_to, details=body, \
- subject=obj.subject, email_from=email_from, \
- message_id=message_id, attach=attach)
-
- x_headers = dict()
- #x_headers = {
- # 'Reply-To':"%s" % case.section_id.reply_to,
- #}
+ x_headers = {
+ 'model': model,
+ 'resource-id': res_id
+ }
if message_id:
x_headers['References'] = "%s" % (message_id)
@@ -127,13 +124,19 @@ class crm_send_new_email(osv.osv_memory):
emails,
obj.subject,
body,
+ email_cc=email_cc,
attach=attach,
- reply_to=case.section_id.reply_to,
+ reply_to=case.section_id and case.section_id.reply_to or email_from,
openobject_id=str(case.id),
x_headers=x_headers
)
-
+ if not flag:
+ raise osv.except_osv(_('Error!'), _('Unable to send mail. Please check SMTP is configured properly.'))
if flag:
+ case_pool._history(cr, uid, [case], _('Send'), history=True, \
+ email=obj.email_to, details=body, \
+ subject=obj.subject, email_from=email_from, \
+ message_id=message_id, attach=attach)
if obj.state == 'unchanged':
pass
elif obj.state == 'done':
@@ -196,7 +199,7 @@ class crm_send_new_email(osv.osv_memory):
include_original = context and context.get('include_original', False) or False
res = {}
for hist in hist_obj.browse(cr, uid, res_ids, context=context):
- model = hist.model_id.model
+ model = hist.model
# In the case where the crm.case does not exist in the database
if not model:
@@ -225,10 +228,10 @@ class crm_send_new_email(osv.osv_memory):
original = [header, sender, to, sentdate, desc, signature]
- res['text']= '\n'.join(original)
+ res['text']= '\n\n\n' + '\n'.join(original)
if 'subject' in fields:
- res.update({'subject': '[%s] %s' %(str(case.id), case.name or '')})
+ res.update({'subject': 'Re: %s' %(hist.name or '')})
if 'state' in fields:
res['state']='pending'
return res
diff --git a/addons/crm/wizard/crm_send_email_view.xml b/addons/crm/wizard/crm_send_email_view.xml
index f56bf5e6a88..c0125014c1a 100644
--- a/addons/crm/wizard/crm_send_email_view.xml
+++ b/addons/crm/wizard/crm_send_email_view.xml
@@ -9,13 +9,15 @@
crm.send.mail
form
-
-
+
+
+
-
-
+
+
+
@@ -31,8 +33,8 @@
-
-
+
+
diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py
index e8a14df42a8..8ccd8acd0a4 100644
--- a/addons/crm_claim/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -21,7 +21,7 @@
from osv import fields, osv
from crm import crm
-
+import time
class crm_claim(osv.osv, crm.crm_case):
"""
Crm claim
@@ -29,10 +29,8 @@ class crm_claim(osv.osv, crm.crm_case):
_name = "crm.claim"
_description = "Claim Cases"
_order = "id desc"
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread']
_columns = {
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
@@ -90,6 +88,8 @@ class crm_claim(osv.osv, crm.crm_case):
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
}
_defaults = {
@@ -100,9 +100,46 @@ class crm_claim(osv.osv, crm.crm_case):
'email_from':crm.crm_case. _get_default_email,
'state': lambda *a: 'draft',
'section_id':crm.crm_case. _get_section,
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
}
+
+ def onchange_partner_id(self, cr, uid, ids, part, email=False):
+ """This function returns value of partner address based on partner
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case IDs
+ @param part: Partner's id
+ @email: Partner's email ID
+ """
+ if not part:
+ return {'value': {'partner_address_id': False,
+ 'email_from': False,
+ 'partner_phone': False,
+ 'partner_mobile': False
+ }}
+ addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
+ data = {'partner_address_id': addr['contact']}
+ data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
+ print data
+ return {'value': data}
+
+ def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
+ """This function returns value of partner email based on Partner Address
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case IDs
+ @param add: Id of Partner's address
+ @email: Partner's email ID
+ """
+ if not add:
+ return {'value': {'email_from': False}}
+ address = self.pool.get('res.partner.address').browse(cr, uid, add)
+ return {'value': {'email_from': address.email, 'partner_phone': address.phone, 'partner_mobile': address.mobile}}
+
crm_claim()
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 487a116ca1d..48cc9055c58 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -58,7 +58,6 @@
tree
-
@@ -67,6 +66,8 @@
+
+
-
+
+
-
-
+
+
@@ -291,12 +293,37 @@
widget="selection"/>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm_fundraising/crm_fundraising.py b/addons/crm_fundraising/crm_fundraising.py
index 356c3baec73..2fd7f4c6f52 100644
--- a/addons/crm_fundraising/crm_fundraising.py
+++ b/addons/crm_fundraising/crm_fundraising.py
@@ -28,10 +28,8 @@ class crm_fundraising(osv.osv, crm.crm_case):
_name = "crm.fundraising"
_description = "Fund Raising Cases"
_order = "id desc"
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread']
_columns = {
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID'),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
@@ -87,6 +85,8 @@ class crm_fundraising(osv.osv, crm.crm_case):
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
}
_defaults = {
diff --git a/addons/crm_fundraising/crm_fundraising_view.xml b/addons/crm_fundraising/crm_fundraising_view.xml
index 4824cc8b3a3..68705d73d8e 100644
--- a/addons/crm_fundraising/crm_fundraising_view.xml
+++ b/addons/crm_fundraising/crm_fundraising_view.xml
@@ -72,21 +72,21 @@
-
-
+
+
@@ -133,15 +133,9 @@
-
-
@@ -149,6 +143,12 @@
states="open,draft,pending" type="object"
groups="base.group_extended"
icon="gtk-go-up" />
+
+
@@ -304,9 +304,15 @@
domain="[]"
context="{'group_by':'user_id'}" />
-
+
+
+
diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py
index d07d2261013..f6106db5903 100644
--- a/addons/crm_helpdesk/crm_helpdesk.py
+++ b/addons/crm_helpdesk/crm_helpdesk.py
@@ -21,6 +21,7 @@
from crm import crm
from osv import fields, osv
+import time
class crm_helpdesk(osv.osv, crm.crm_case):
""" Helpdesk Cases """
@@ -28,10 +29,8 @@ class crm_helpdesk(osv.osv, crm.crm_case):
_name = "crm.helpdesk"
_description = "Helpdesk Cases"
_order = "id desc"
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread']
_columns = {
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
@@ -87,6 +86,7 @@ class crm_helpdesk(osv.osv, crm.crm_case):
'partner_address_id': crm.crm_case._get_default_partner_address,
'email_from': crm.crm_case. _get_default_email,
'state': lambda *a: 'draft',
+ 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'section_id': crm.crm_case. _get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
index f91650a315a..c077c219162 100644
--- a/addons/crm_helpdesk/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -29,7 +29,7 @@
-
+
-
-
+ states="draft,pending" string="Open"
+ type="object" icon="gtk-go-forward" />
+ states="draft,open" string="Pending"
+ type="object" icon="gtk-media-pause" />
+ states="open,draft,pending"
+ string="Escalate" type="object"
+ icon="gtk-go-up" />
+
+
+ states="done,cancel"
+ string="Reset to Draft" type="object"
+ icon="gtk-convert" />
@@ -179,24 +179,18 @@
-
-
+
+
-
-
@@ -204,6 +198,12 @@
groups="base.group_extended"
states="open,draft,pending" type="object"
icon="gtk-go-up" />
+
+
@@ -255,12 +255,30 @@
-
+
+
+
+
+
+
+
+
diff --git a/addons/crm_profiling/i18n/el.po b/addons/crm_profiling/i18n/el.po
index ce6a20ea15a..e253ca4c28c 100644
--- a/addons/crm_profiling/i18n/el.po
+++ b/addons/crm_profiling/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py
index 91dfed96f11..27091dda8bd 100644
--- a/addons/delivery/stock.py
+++ b/addons/delivery/stock.py
@@ -28,8 +28,6 @@ import decimal_precision as dp
# Overloaded stock_picking to manage carriers :
class stock_picking(osv.osv):
- _name = "stock.picking"
- _description = "Packing List"
_inherit = 'stock.picking'
def _cal_weight(self, cr, uid, ids, name, args, context=None):
diff --git a/addons/document/__init__.py b/addons/document/__init__.py
index 694989bdd79..12306b0499b 100644
--- a/addons/document/__init__.py
+++ b/addons/document/__init__.py
@@ -27,5 +27,6 @@ import directory_content
import directory_report
import document
import report
+import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/__openerp__.py b/addons/document/__openerp__.py
index e7d3f767010..5e1aa939b54 100644
--- a/addons/document/__openerp__.py
+++ b/addons/document/__openerp__.py
@@ -45,6 +45,7 @@
'update_xml': [
'document_view.xml',
'document_data.xml',
+ 'wizard/document_configuration_view.xml',
'security/document_security.xml',
'security/ir.model.access.csv',
'report/document_report_view.xml',
diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py
index 1d0bbf3ed7c..e275adcb5c6 100644
--- a/addons/document/document_directory.py
+++ b/addons/document/document_directory.py
@@ -112,7 +112,7 @@ class document_directory(osv.osv):
while d2 and d2.parent_id:
s = d2.name + (s and ('/' + s) or '')
d2 = d2.parent_id
- res.append((d.id, s))
+ res.append((d.id, s or d.name))
return res
def get_full_path(self, cr, uid, dir_id, context=None):
diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml
index 29f3617d64f..8fcd791144e 100644
--- a/addons/document/document_view.xml
+++ b/addons/document/document_view.xml
@@ -193,10 +193,7 @@
-
-
-
@@ -219,7 +216,9 @@
-
+
+
+
diff --git a/addons/document/i18n/el.po b/addons/document/i18n/el.po
index 9b425c31b89..5cc1498a931 100644
--- a/addons/document/i18n/el.po
+++ b/addons/document/i18n/el.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document
diff --git a/addons/document/i18n/es.po b/addons/document/i18n/es.po
index c491e4daa8d..8c53f9f604e 100644
--- a/addons/document/i18n/es.po
+++ b/addons/document/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document
diff --git a/addons/document/security/ir.model.access.csv b/addons/document/security/ir.model.access.csv
index 245bcbffeab..a4412195745 100644
--- a/addons/document/security/ir.model.access.csv
+++ b/addons/document/security/ir.model.access.csv
@@ -19,3 +19,5 @@
"access_report_document_file_group_system","report.document.file group system","model_report_document_file","base.group_system",1,0,0,0
"access_report_document_wall_group_document_manager","report.document.wall document manager","model_report_document_wall","document.group_document_manager",1,0,0,0
"access_report_document_wall_group_system","report.document.wall group system","model_report_document_wall","base.group_system",1,0,0,0
+"access_document_configuation","document.configuration document manager","model_document_configuration","document.group_document_manager",1,1,1,1
+"access_document_configuation_system","document.configuration group system","model_document_configuration","base.group_system",1,1,1,1
diff --git a/addons/document/std_index.py b/addons/document/std_index.py
index c4f7d787d4d..2facb14eeb3 100644
--- a/addons/document/std_index.py
+++ b/addons/document/std_index.py
@@ -19,10 +19,11 @@
#
##############################################################################
+from content_index import indexer, cntIndex
+from subprocess import Popen, PIPE
import StringIO
import odt2txt
-from subprocess import Popen, PIPE
-from content_index import indexer, cntIndex
+import sys, zipfile, xml.dom.minidom
def _to_unicode(s):
try:
@@ -36,6 +37,15 @@ def _to_unicode(s):
except UnicodeError:
return s
+def textToString(element) :
+ buffer = u""
+ for node in element.childNodes :
+ if node.nodeType == xml.dom.Node.TEXT_NODE :
+ buffer += node.nodeValue
+ elif node.nodeType == xml.dom.Node.ELEMENT_NODE :
+ buffer += textToString(node)
+ return buffer
+
class TxtIndex(indexer):
def _getMimeTypes(self):
return ['text/plain','text/html','text/diff','text/xml', 'text/*',
@@ -44,7 +54,7 @@ class TxtIndex(indexer):
def _getExtensions(self):
return ['.txt', '.py']
- def _doIndexContent(self, content):
+ def _doIndexContent(self,content):
return content
cntIndex.register(TxtIndex())
@@ -56,15 +66,24 @@ class PptxIndex(indexer):
def _getExtensions(self):
return ['.pptx']
- def _doIndexFile(self, fname):
- # pptx2txt.pl package not support in windows platform.
- # Download pptx2txt package from http://sourceforge.net/projects/pptx2txt/" link.
- # To install this tool, just copy pptx2txt.pl to appropriate place (e.g. /usr/bin directory)
- fp = Popen(['pptx2txt.pl', fname], shell=False, stdout=PIPE).stdout
- fp.read()
- file_obj = open(str(fname + ".txt"), "r")
- data = file_obj.read()
- return _to_unicode(data)
+ def _doIndexFile(self,fname):
+ def toString () :
+ """ Converts the document to a string. """
+ buffer = u""
+ for val in ["a:t"]:
+ for paragraph in content.getElementsByTagName(val) :
+ buffer += textToString(paragraph) + "\n"
+ return buffer
+
+ data = []
+ zip = zipfile.ZipFile(fname)
+ files = filter(lambda x: x.startswith('ppt/slides/slide'), zip.namelist())
+ for i in range(1, len(files) + 1):
+ content = xml.dom.minidom.parseString(zip.read('ppt/slides/slide%s.xml' % str(i)))
+ res = toString().encode('ascii','replace')
+ data.append(res)
+
+ return _to_unicode('\n'.join(data))
cntIndex.register(PptxIndex())
@@ -76,33 +95,60 @@ class DocIndex(indexer):
return ['.doc']
def _doIndexFile(self,fname):
- fp = Popen(['antiword', fname], shell=False, stdout=PIPE).stdout
- return _to_unicode( fp.read())
+ #fp = Popen(['antiword', fname], shell=False, stdout=PIPE).stdout
+ return _to_unicode( 'None')
cntIndex.register(DocIndex())
class DocxIndex(indexer):
def _getMimeTypes(self):
return [ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
-
+
def _getExtensions(self):
return ['.docx']
- def _doIndexFile(self, fname):
- # docx2txt.pl package not support in windows platform.
- # Download docx2txt package from "http://sourceforge.net/projects/docx2txt/" link.
- # In case, you don't want to use Makefile for installation, you can follow these steps for manual installation.
- # Copy docx2txt.pl, docx2txt.sh and docx2txt.config to appropriate place (e.g. /usr/bin directory) . used following command.
- # --> cp docx2txt.pl docx2txt.sh docx2txt.config /usr/bin/
+ def _doIndexFile(self,fname):
+ zip = zipfile.ZipFile(fname)
+ content = xml.dom.minidom.parseString(zip.read("word/document.xml"))
+ def toString () :
+ """ Converts the document to a string. """
+ buffer = u""
+ for val in ["w:p", "w:h", "text:list"]:
+ for paragraph in content.getElementsByTagName(val) :
+ buffer += textToString(paragraph) + "\n"
+ return buffer
- fp = Popen(['docx2txt.pl', fname], shell=False, stdout=PIPE).stdout
- fp.read()
- file_obj = open(str(fname + ".txt"), "r")
- data = file_obj.read()
- return _to_unicode(data)
+ res = toString().encode('ascii','replace')
+
+ return _to_unicode(res)
cntIndex.register(DocxIndex())
+
+class XlsxIndex(indexer):
+ def _getMimeTypes(self):
+ return [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
+
+ def _getExtensions(self):
+ return ['.xlsx']
+
+ def _doIndexFile(self,fname):
+ zip = zipfile.ZipFile(fname)
+ content = xml.dom.minidom.parseString(zip.read("xl/sharedStrings.xml"))
+ def toString () :
+ """ Converts the document to a string. """
+ buffer = u""
+ for val in ["t"]:
+ for paragraph in content.getElementsByTagName(val) :
+ buffer += textToString(paragraph) + "\n"
+ return buffer
+
+ res = toString().encode('ascii','replace')
+
+ return _to_unicode(res)
+
+cntIndex.register(XlsxIndex())
+
class PdfIndex(indexer):
def _getMimeTypes(self):
return [ 'application/pdf']
diff --git a/addons/account_report_india/wizard/__init__.py b/addons/document/wizard/__init__.py
old mode 100755
new mode 100644
similarity index 87%
rename from addons/account_report_india/wizard/__init__.py
rename to addons/document/wizard/__init__.py
index 2a870d96fad..b143b583426
--- a/addons/account_report_india/wizard/__init__.py
+++ b/addons/document/wizard/__init__.py
@@ -1,8 +1,8 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
+# Copyright (C) 2004-2010 Tiny SPRL ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -18,6 +18,4 @@
# along with this program. If not, see .
#
##############################################################################
-
-import account_bs_report
-import account_pl_report
\ No newline at end of file
+import document_configuration
diff --git a/addons/document/wizard/document_configuration.py b/addons/document/wizard/document_configuration.py
new file mode 100644
index 00000000000..a497eb6af90
--- /dev/null
+++ b/addons/document/wizard/document_configuration.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+from osv import osv, fields
+class document_configuration(osv.osv_memory):
+
+ _name='document.configuration'
+ _description = 'Auto Directory Configuration'
+ _inherit = 'res.config'
+
+ _columns = {
+ 'sale_order' : fields.boolean('Sale Order', help="Auto directory configuration for Sale Orders and Quotation with report."),
+ 'product' : fields.boolean('Product', help="Auto directory configuration for Products."),
+ 'project': fields.boolean('Project', help="Auto directory configuration for Projects."),
+ }
+
+
+ def execute(self, cr, uid, ids, context=None):
+ conf_id = ids and ids[0] or False
+ conf = self.browse(cr, uid, conf_id, context)
+ dir_pool = self.pool.get('document.directory')
+ data_pool = self.pool.get('ir.model.data')
+ model_pool = self.pool.get('ir.model')
+ content_pool = self.pool.get('document.directory.content')
+ if conf.sale_order and self.pool.get('sale.order'):
+ # Sale order
+ dir_data_id = data_pool._get_id(cr, uid, 'document', 'dir_sale_order_all')
+ if dir_data_id:
+ sale_dir_id = data_pool.browse(cr, uid, dir_data_id, context=context).res_id
+ else:
+ sale_dir_id = data_pool.create(cr, uid, {'name': 'Sale Orders'})
+ mid = model_pool.search(cr, uid, [('model','=','sale.order')])
+ dir_pool.write(cr, uid, [sale_dir_id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': '[]',
+ })
+ # Qutation
+ dir_data_id = data_pool._get_id(cr, uid, 'document', 'dir_sale_order_quote')
+ if dir_data_id:
+ quta_dir_id = data_pool.browse(cr, uid, dir_data_id, context=context).res_id
+ else:
+ quta_dir_id = data_pool.create(cr, uid, {'name': 'Sale Quotations'})
+
+ dir_pool.write(cr, uid, [quta_dir_id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': "[('state','=','draft')]",
+ })
+ # Sale Order Report
+ order_report_data_id = data_pool._get_id(cr, uid, 'sale', 'report_sale_order')
+ if order_report_data_id:
+ order_report_id = data_pool.browse(cr, uid, order_report_data_id, context=context).res_id
+
+ content_pool.create(cr, uid, {
+ 'name': "Print Order",
+ 'suffix': "_print",
+ 'report_id': order_report_id,
+ 'extension': '.pdf',
+ 'include_name': 1,
+ 'directory_id': sale_dir_id,
+ })
+
+ content_pool.create(cr, uid, {
+ 'name': "Print Qutation",
+ 'suffix': "_print",
+ 'report_id': order_report_id,
+ 'extension': '.pdf',
+ 'include_name': 1,
+ 'directory_id': quta_dir_id,
+ })
+
+
+ if conf.product and self.pool.get('product.product'):
+ # Product
+ dir_data_id = data_pool._get_id(cr, uid, 'document', 'dir_product')
+ if dir_data_id:
+ product_dir_id = data_pool.browse(cr, uid, dir_data_id, context=context).res_id
+ else:
+ product_dir_id = data_pool.create(cr, uid, {'name': 'Products'})
+
+ mid = model_pool.search(cr, uid, [('model','=','product.product')])
+ dir_pool.write(cr, uid, [product_dir_id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ })
+
+ if conf.project and self.pool.get('account.analytic.account'):
+ # Project
+ dir_data_id = data_pool._get_id(cr, uid, 'document', 'dir_project')
+ if dir_data_id:
+ project_dir_id = data_pool.browse(cr, uid, dir_data_id, context=context).res_id
+ else:
+ project_dir_id = data_pool.create(cr, uid, {'name': 'Projects'})
+
+ mid = model_pool.search(cr, uid, [('model','=','account.analytic.account')])
+ dir_pool.write(cr, uid, [project_dir_id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': '[]',
+ 'ressource_tree': 1
+ })
+document_configuration()
diff --git a/addons/document/wizard/document_configuration_view.xml b/addons/document/wizard/document_configuration_view.xml
new file mode 100644
index 00000000000..c6f40deb429
--- /dev/null
+++ b/addons/document/wizard/document_configuration_view.xml
@@ -0,0 +1,50 @@
+
+
+
+ Auto Configure Directory
+ document.configuration
+ form
+
+
+
+
+ Auto Configure
+
+
+ Resource Directory Configuration
+
+
+ Choose the following Resouces to auto directory configuration.
+
+
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto Configure Directory
+ ir.actions.act_window
+ document.configuration
+
+ form
+ form
+ new
+
+
+
+
+
+
+
+
diff --git a/addons/document_ftp/__init__.py b/addons/document_ftp/__init__.py
index 45ec4a6b67f..af514df8985 100644
--- a/addons/document_ftp/__init__.py
+++ b/addons/document_ftp/__init__.py
@@ -18,7 +18,7 @@
# along with this program. If not, see .
#
##############################################################################
-import doc_conf_wizard
import ftpserver
+import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ftp/__openerp__.py b/addons/document_ftp/__openerp__.py
index 18042dabf93..a2b88d0a2a2 100644
--- a/addons/document_ftp/__openerp__.py
+++ b/addons/document_ftp/__openerp__.py
@@ -33,7 +33,8 @@
'depends': ['base', 'document'],
'init_xml': [],
'update_xml': [
- 'document_ftp_view.xml',
+ 'wizard/ftp_configuration_view.xml',
+ 'wizard/ftp_browse_view.xml',
'security/ir.model.access.csv'
],
'demo_xml': [],
diff --git a/addons/document_ftp/doc_conf_wizard.py b/addons/document_ftp/doc_conf_wizard.py
deleted file mode 100644
index 0f2f970572e..00000000000
--- a/addons/document_ftp/doc_conf_wizard.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see
-#
-##############################################################################
-
-import base64
-
-from osv import osv, fields
-from osv.orm import except_orm
-from tools import config
-import urlparse
-
-import os
-
-class document_configuration_wizard(osv.osv_memory):
-
- _name='document.configuration.wizard'
- _description = 'Auto Directory Configuration'
- _inherit = 'res.config'
- _rec_name = 'host'
- _columns = {
- 'host': fields.char('Address', size=64,
- help="Server address or IP and port to which users should connect to for DMS access",
- required=True),
- }
-
- _defaults = {
- 'host': config.get('ftp_server_host', 'localhost') + ':' + config.get('ftp_server_port', '8021'),
- }
-
- def execute(self, cr, uid, ids, context=None):
- conf = self.browse(cr, uid, ids[0], context)
- obj=self.pool.get('document.directory')
- objid=self.pool.get('ir.model.data')
-
- if self.pool.get('sale.order'):
- id = objid._get_id(cr, uid, 'document', 'dir_sale_order_all')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','sale.order')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': '[]',
- })
- aid = objid._get_id(cr, uid, 'sale', 'report_sale_order')
- aid = objid.browse(cr, uid, aid, context=context).res_id
-
- self.pool.get('document.directory.content').create(cr, uid, {
- 'name': "Print Order",
- 'suffix': "_print",
- 'report_id': aid,
- 'extension': '.pdf',
- 'include_name': 1,
- 'directory_id': id,
- })
- id = objid._get_id(cr, uid, 'document', 'dir_sale_order_quote')
- id = objid.browse(cr, uid, id, context=context).res_id
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': "[('state','=','draft')]",
- })
-
- if self.pool.get('product.product'):
- id = objid._get_id(cr, uid, 'document', 'dir_product')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','product.product')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- })
-
- if self.pool.get('stock.location'):
- aid = objid._get_id(cr, uid, 'stock', 'report_product_history')
- aid = objid.browse(cr, uid, aid, context=context).res_id
-
- self.pool.get('document.directory.content').create(cr, uid, {
- 'name': "Product Stock",
- 'suffix': "_stock_forecast",
- 'report_id': aid,
- 'extension': '.pdf',
- 'include_name': 1,
- 'directory_id': id,
- })
-
- if self.pool.get('account.analytic.account'):
- id = objid._get_id(cr, uid, 'document', 'dir_project')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','account.analytic.account')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': '[]',
- 'ressource_tree': 1
- })
-
- # Update the action for FTP browse.
- aid = objid._get_id(cr, uid, 'document_ftp', 'action_document_browse')
- aid = objid.browse(cr, uid, aid, context=context).res_id
- self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost:8021')+'/'})
-document_configuration_wizard()
diff --git a/addons/document_ftp/security/ir.model.access.csv b/addons/document_ftp/security/ir.model.access.csv
index c9c082f4397..b3ffdbd5350 100644
--- a/addons/document_ftp/security/ir.model.access.csv
+++ b/addons/document_ftp/security/ir.model.access.csv
@@ -1,3 +1,6 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
-"access_document_configuation_wizard","document.configuration.wizard document manager","model_document_configuration_wizard","document.group_document_manager",1,1,1,1
-"access_document_configuation_wizard_sytem","document.configuration.wizard group system","model_document_configuration_wizard","base.group_system",1,1,1,1
+"access_document_ftp_browse","document.ftp.browse document manager","model_document_ftp_browse","document.group_document_manager",1,1,1,1
+"access_document_ftp_browse","document.ftp.browse group system","model_document_ftp_browse","base.group_system",1,1,1,1
+"access_document_ftp_configuation","document.ftp.configuration document manager","model_document_ftp_configuration","document.group_document_manager",1,1,1,1
+"access_document_ftp_configuation_system","document.ftp.configuration group system","model_document_ftp_configuration","base.group_system",1,1,1,1
+
diff --git a/addons/account_report_india/__openerp__.py b/addons/document_ftp/wizard/__init__.py
similarity index 56%
rename from addons/account_report_india/__openerp__.py
rename to addons/document_ftp/wizard/__init__.py
index 0765af339a1..40997cc6b90 100644
--- a/addons/account_report_india/__openerp__.py
+++ b/addons/document_ftp/wizard/__init__.py
@@ -1,8 +1,8 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
+# Copyright (C) 2004-2010 Tiny SPRL ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -18,30 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
+import ftp_browse
+import ftp_configuration
-{
- "name" : "Accounting Reports",
- "version" : "1.0",
- "depends" : [
- "account"
- ],
- "author" : "Tiny ERP",
- "description": """Accounting Reports
-Modules gives the 2 most Important Reports for the Accounting
-* Profit and Loss Account
-* Balance Sheet
- """,
- "website" : "http://tinyerp.com/module_account.html",
- "category" : "Generic Modules/Accounting",
- "init_xml" : [
- ],
- "demo_xml" : [
-
- ],
- "update_xml" : [
- "wizard/account_pl_report_view.xml",
- "wizard/account_bs_report_view.xml"
- ],
- "active": False,
- "installable": True
-}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ftp/wizard/ftp_browse.py b/addons/document_ftp/wizard/ftp_browse.py
new file mode 100644
index 00000000000..d033302f22a
--- /dev/null
+++ b/addons/document_ftp/wizard/ftp_browse.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from osv import osv, fields
+from tools.translate import _
+from document_ftp import ftpserver
+class document_ftp_browse(osv.osv_memory):
+ _name = 'document.ftp.browse'
+ _description = 'Document FTP Browse'
+
+ _columns = {
+ 'url' : fields.char('FTP Server', size=64, required=True),
+ }
+
+ def default_get(self, cr, uid, fields, context=None):
+ res = {}
+ if 'url' in fields:
+ user_pool = self.pool.get('res.users')
+ current_user = user_pool.browse(cr, uid, uid, context=context)
+ dir_pool = self.pool.get('document.directory')
+ data_pool = self.pool.get('ir.model.data')
+ aid = data_pool._get_id(cr, uid, 'document_ftp', 'action_document_browse')
+ aid = data_pool.browse(cr, uid, aid, context=context).res_id
+ ftp_url = self.pool.get('ir.actions.url').browse(cr, uid, aid, context=context)
+ url = ftp_url.url and ftp_url.url.split('ftp://') or []
+ if url:
+ url = url[1]
+ else:
+ url = '%s:%s' %(ftpserver.HOST, ftpserver.PORT)
+ res['url'] = 'ftp://%s@%s'%(current_user.login, url)
+ return res
+
+ def browse_ftp(self, cr, uid, ids, context):
+ data_id = ids and ids[0] or False
+ data = self.browse(cr, uid, data_id, context)
+ final_url = data.url
+ return {
+ 'type': 'ir.actions.act_url',
+ 'url':final_url,
+ 'target': 'new'
+ }
+document_ftp_browse()
+
diff --git a/addons/document_ftp/wizard/ftp_browse_view.xml b/addons/document_ftp/wizard/ftp_browse_view.xml
new file mode 100644
index 00000000000..44cedccfc3e
--- /dev/null
+++ b/addons/document_ftp/wizard/ftp_browse_view.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ Document FTP Browse
+ document.ftp.browse
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Document Browse
+ ir.actions.act_window
+ document.ftp.browse
+
+ form
+ form
+ new
+
+
+
+
+
+
diff --git a/addons/document_ftp/wizard/ftp_configuration.py b/addons/document_ftp/wizard/ftp_configuration.py
new file mode 100644
index 00000000000..40926bdf7c9
--- /dev/null
+++ b/addons/document_ftp/wizard/ftp_configuration.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+from tools import config
+import urlparse
+
+import os
+
+class document_ftp_configuration(osv.osv_memory):
+
+ _name='document.ftp.configuration'
+ _description = 'Auto Directory Configuration'
+ _inherit = 'res.config'
+ _rec_name = 'host'
+ _columns = {
+ 'host': fields.char('Address', size=64,
+ help="Server address or IP and port to which users should connect to for DMS access",
+ required=True),
+ }
+
+ _defaults = {
+ 'host': config.get('ftp_server_host', 'localhost') + ':' + config.get('ftp_server_port', '8021'),
+ }
+
+ def execute(self, cr, uid, ids, context=None):
+ conf = self.browse(cr, uid, ids[0], context)
+ dir_pool = self.pool.get('document.directory')
+ data_pool = self.pool.get('ir.model.data')
+ # Update the action for FTP browse.
+ aid = data_pool._get_id(cr, uid, 'document_ftp', 'action_document_browse')
+ aid = data_pool.browse(cr, uid, aid, context=context).res_id
+ self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost:8021')+'/'})
+document_ftp_configuration()
diff --git a/addons/document_ftp/document_ftp_view.xml b/addons/document_ftp/wizard/ftp_configuration_view.xml
similarity index 76%
rename from addons/document_ftp/document_ftp_view.xml
rename to addons/document_ftp/wizard/ftp_configuration_view.xml
index d3f4c09498c..df3aee360af 100644
--- a/addons/document_ftp/document_ftp_view.xml
+++ b/addons/document_ftp/wizard/ftp_configuration_view.xml
@@ -3,26 +3,19 @@
Browse Files
ftp://localhost:8021/
-
-
+
- Auto Configure Directory
- document.configuration.wizard
+ FTP Server Configuration
+ document.ftp.configuration
form
- Auto Configure
+ FTP Server Configuration
FTP Server Configuration
@@ -43,9 +36,9 @@
- Auto Configure Directory
+ FTP Server Configuration
ir.actions.act_window
- document.configuration.wizard
+ document.ftp.configuration
form
form
diff --git a/addons/document_webdav/i18n/el.po b/addons/document_webdav/i18n/el.po
index eaf94e5c066..7870348b677 100644
--- a/addons/document_webdav/i18n/el.po
+++ b/addons/document_webdav/i18n/el.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document_webdav_old
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index 37b38774a7d..133a47563a8 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -108,7 +108,7 @@ class email_template(osv.osv):
'enforce_from_account':fields.many2one(
'email_template.account',
string="Enforce From Account",
- help="Emails will be sent only from this account."),
+ help="Emails will be sent only from this account(which are approved)."),
'from_email' : fields.related('enforce_from_account', 'email_id',
type='char', string='From',),
'def_to':fields.char(
@@ -580,8 +580,8 @@ class email_template(osv.osv):
context)
print 'Sending', mailbox_id
- self.pool.get('email_template.mailbox').send_this_mail(cursor, user, [mailbox_id], context)
return mailbox_id
+
def generate_mail(self,
cursor,
@@ -595,6 +595,7 @@ class email_template(osv.osv):
if not template:
raise Exception("The requested template could not be loaded")
print 'loaded', record_ids
+ result = True
for record_id in record_ids:
mailbox_id = self._generate_mailbox_item_from_template(
cursor,
@@ -625,7 +626,9 @@ class email_template(osv.osv):
{'folder':'outbox'},
context=context
)
- return True
+ # TODO : manage return value of all the records
+ result = self.pool.get('email_template.mailbox').send_this_mail(cursor, user, [mailbox_id], context)
+ return result
email_template()
@@ -641,7 +644,7 @@ class email_template_preview(osv.osv_memory):
if 'template_id' in context.keys():
ref_obj_id = self.pool.get('email.template').read(cr, uid, context['template_id'], ['object_name'], context)
ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id['object_name'][0], ['model'], context)['model']
- ref_obj_ids = self.pool.get(ref_obj_name).search(cr, uid, [], context=context)
+ ref_obj_ids = self.pool.get(ref_obj_name).search(cr, uid, [], 0, 20, 'id desc', context=context)
ref_obj_recs = self.pool.get(ref_obj_name).name_get(cr, uid, ref_obj_ids, context)
return ref_obj_recs
diff --git a/addons/email_template/email_template_account.py b/addons/email_template/email_template_account.py
index 0bcf3c3d099..9ea1cd5b8fa 100644
--- a/addons/email_template/email_template_account.py
+++ b/addons/email_template/email_template_account.py
@@ -97,9 +97,12 @@ class email_template_account(osv.osv):
context
)['name'],
'state':lambda * a:'draft',
+ 'smtpport':lambda *a:25,
+ 'smtpserver':lambda *a:'localhost',
+ 'company':lambda *a:'yes',
'user':lambda self, cursor, user, context:user,
- 'send_pref':lambda * a: 'html',
- 'smtptls':lambda * a:True,
+ 'send_pref':lambda *a: 'html',
+ 'smtptls':lambda *a:True,
}
_sql_constraints = [
@@ -266,7 +269,7 @@ class email_template_account(osv.osv):
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
+ #TODO: Replace all this with a single email object
if body is None:
body = {}
if payload is None:
@@ -320,19 +323,20 @@ class email_template_account(osv.osv):
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
+ return {'error_msg': "Server Send Error\nDescription: %s"%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
+ return {'error_msg': "Server Send Error\nDescription: %s"%error}
#The mail sending is complete
serv.close()
logger.notifyChannel(_("Email Template"), netsvc.LOG_INFO, _("Mail from Account %s successfully Sent.") % (id))
return True
else:
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Account not approved") % id)
+ return {'error_msg':"Mail from Account %s failed. Probable Reason:Account not approved"% id}
def extracttime(self, time_as_string):
"""
@@ -394,7 +398,6 @@ class email_template_account(osv.osv):
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)]
diff --git a/addons/email_template/email_template_mailbox.py b/addons/email_template/email_template_mailbox.py
index fe9ca334d21..b89a9aeda26 100644
--- a/addons/email_template/email_template_mailbox.py
+++ b/addons/email_template/email_template_mailbox.py
@@ -56,18 +56,19 @@ class email_template_mailbox(osv.osv):
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)
+ error = result['error_msg']
+ self.historise(cr, uid, [id], error, 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
+ return result
def historise(self, cr, uid, ids, message='', context=None):
for id in ids:
diff --git a/addons/email_template/email_template_view.xml b/addons/email_template/email_template_view.xml
index 934a7324b07..1d574ff8675 100644
--- a/addons/email_template/email_template_view.xml
+++ b/addons/email_template/email_template_view.xml
@@ -8,33 +8,29 @@
form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
Template Preview
email_template.preview
@@ -60,14 +56,16 @@
-
-
+
+
-
-
-
+
+
+
+
+
diff --git a/addons/event_project/i18n/el.po b/addons/event_project/i18n/el.po
new file mode 100644
index 00000000000..6a5cc277123
--- /dev/null
+++ b/addons/event_project/i18n/el.po
@@ -0,0 +1,88 @@
+# Greek translation for openobject-addons
+# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2009-08-28 16:01+0000\n"
+"PO-Revision-Date: 2010-06-24 22:21+0000\n"
+"Last-Translator: Panayiotis Konstantinidis \n"
+"Language-Team: Greek \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. module: event_project
+#: constraint:ir.ui.view:0
+msgid "Invalid XML for View Architecture!"
+msgstr "Λανθασμένο XML για προβολή αρχιτεκτονικής!"
+
+#. module: event_project
+#: model:ir.actions.wizard,name:event_project.wizard_event_task
+msgid "Tasks"
+msgstr "Εργασίες"
+
+#. module: event_project
+#: wizard_button:event.project,init,done:0
+msgid "Ok"
+msgstr "Εντάξει"
+
+#. module: event_project
+#: model:ir.module.module,description:event_project.module_meta_information
+msgid ""
+"Organization and management of events.\n"
+"\n"
+" This module allow you to create retro planning for managing your "
+"events.\n"
+msgstr ""
+"Οργάνωση και διαχείριση συμβάντων.\n"
+"\n"
+" Αυτή το τμήμα του προγράμματος σας επιτρέπει να κάνετε ανασχεδιασμό για "
+"τη διαχείριση των συμβάντων σας.\n"
+
+#. module: event_project
+#: view:event.event:0
+msgid "Remaining Tasks"
+msgstr "Εργασίες που παραμένουν"
+
+#. module: event_project
+#: model:ir.module.module,shortdesc:event_project.module_meta_information
+msgid "Event - Project"
+msgstr "Συμβάν - Έργο"
+
+#. module: event_project
+#: field:event.event,project_id:0
+#: wizard_field:event.project,init,project_id:0
+#: model:ir.actions.wizard,name:event_project.event_wiz
+msgid "Project"
+msgstr "Έργο"
+
+#. module: event_project
+#: field:event.event,task_ids:0
+msgid "Project tasks"
+msgstr "Εργασίες Έργου"
+
+#. module: event_project
+#: wizard_button:event.project,init,end:0
+msgid "Cancel"
+msgstr "Ακύρωση"
+
+#. module: event_project
+#: view:event.event:0
+msgid "Create Retro-Planning"
+msgstr "Δημιουργία προγραμματισμού"
+
+#. module: event_project
+#: wizard_view:event.project,init:0
+msgid "Event"
+msgstr "Συμβάν"
+
+#. module: event_project
+#: view:event.event:0
+msgid "Tasks management"
+msgstr "Διαχείριση εργασιών"
diff --git a/addons/fetchmail/__openerp__.py b/addons/fetchmail/__openerp__.py
index a1276c11643..31037cca63f 100644
--- a/addons/fetchmail/__openerp__.py
+++ b/addons/fetchmail/__openerp__.py
@@ -24,7 +24,7 @@
{
"name" : "Fetchmail Server",
"version" : "1.0",
- "depends" : ["base"],
+ "depends" : ["base", 'mail_gateway'],
"author" : "Tiny",
"description": """Fetchmail:
* Fetch email from Pop / IMAP server
diff --git a/addons/fetchmail/fetchmail.py b/addons/fetchmail/fetchmail.py
index aa403cc0090..14981c13837 100644
--- a/addons/fetchmail/fetchmail.py
+++ b/addons/fetchmail/fetchmail.py
@@ -19,140 +19,57 @@
#
##############################################################################
-import os
-import re
import time
-import email
-import binascii
-import mimetypes
-
from imaplib import IMAP4
-from imaplib import IMAP4_SSL
-
+from imaplib import IMAP4_SSL
from poplib import POP3
from poplib import POP3_SSL
-from email.header import Header
-from email.header import decode_header
-
import netsvc
-from osv import osv
-from osv import fields
-from tools.translate import _
+from osv import osv, fields
logger = netsvc.Logger()
-def html2plaintext(html, body_id=None, encoding='utf-8'):
- ## (c) Fry-IT, www.fry-it.com, 2007
- ##
- ## download here: http://www.peterbe.com/plog/html2plaintext
- """ from an HTML text, convert the HTML to plain text.
- If @body_id is provided then this is the tag where the
- body (not necessarily ) starts.
- """
- try:
- from BeautifulSoup import BeautifulSoup, SoupStrainer, Comment
- except:
- return html
-
- urls = []
- if body_id is not None:
- strainer = SoupStrainer(id=body_id)
- else:
- strainer = SoupStrainer('body')
-
- soup = BeautifulSoup(html, parseOnlyThese=strainer, fromEncoding=encoding)
- for link in soup.findAll('a'):
- title = link.renderContents()
- for url in [x[1] for x in link.attrs if x[0]=='href']:
- urls.append(dict(url=url, tag=str(link), title=title))
-
- html = soup.__str__()
-
- url_index = []
- i = 0
- for d in urls:
- if d['title'] == d['url'] or 'http://'+d['title'] == d['url']:
- html = html.replace(d['tag'], d['url'])
- else:
- i += 1
- html = html.replace(d['tag'], '%s [%s]' % (d['title'], i))
- url_index.append(d['url'])
-
- html = html.replace('','*').replace(' ','*')
- html = html.replace('','*').replace(' ','*')
- html = html.replace('','*').replace(' ','*')
- html = html.replace('','**').replace(' ','**')
- html = html.replace('','**').replace(' ','**')
- html = html.replace('','/').replace(' ','/')
-
- # the only line breaks we respect is those of ending tags and
- # breaks
-
- html = html.replace('\n',' ')
- html = html.replace(' ', '\n')
- html = html.replace('', '\n')
- html = html.replace('', '\n\n')
- html = re.sub(' ', '\n', html)
- html = html.replace(' ' * 2, ' ')
-
- # for all other tags we failed to clean up, just remove then and
- # complain about them on the stderr
- def desperate_fixer(g):
- #print >>sys.stderr, "failed to clean up %s" % str(g.group())
- return ' '
-
- html = re.sub('<.*?>', desperate_fixer, html)
-
- # lstrip all lines
- html = '\n'.join([x.lstrip() for x in html.splitlines()])
-
- for i, url in enumerate(url_index):
- if i == 0:
- html += '\n\n'
- html += '[%s] %s\n' % (i+1, url)
- return html
-
class email_server(osv.osv):
-
+
_name = 'email.server'
_description = "POP/IMAP Server"
-
+
_columns = {
- 'name':fields.char('Name', size=256, required=True, readonly=False),
- 'active':fields.boolean('Active', required=False),
+ 'name':fields.char('Name', size=256, required=True, readonly=False),
+ 'active':fields.boolean('Active', required=False),
'state':fields.selection([
- ('draft','Not Confirmed'),
- ('wating','Waiting for Verification'),
- ('done','Confirmed'),
- ],'State', select=True, readonly=True),
- 'server' : fields.char('Server', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}),
- 'port' : fields.integer('Port', required=True, readonly=True, states={'draft':[('readonly',False)]}),
+ ('draft', 'Not Confirmed'),
+ ('wating', 'Waiting for Verification'),
+ ('done', 'Confirmed'),
+ ], 'State', select=True, readonly=True),
+ 'server' : fields.char('Server', size=256, required=True, readonly=True, states={'draft':[('readonly', False)]}),
+ 'port' : fields.integer('Port', required=True, readonly=True, states={'draft':[('readonly', False)]}),
'type':fields.selection([
- ('pop','POP Server'),
- ('imap','IMAP Server'),
- ],'State', select=True, readonly=False),
- 'is_ssl':fields.boolean('SSL ?', required=False),
- 'attach':fields.boolean('Add Attachments ?', required=False),
- 'date': fields.date('Date', readonly=True, states={'draft':[('readonly',False)]}),
- 'user' : fields.char('User Name', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}),
- 'password' : fields.char('Password', size=1024, invisible=True, required=True, readonly=True, states={'draft':[('readonly',False)]}),
- 'note': fields.text('Description'),
- 'action_id':fields.many2one('ir.actions.server', 'Reply Email', required=False, domain="[('state','=','email')]"),
- 'object_id': fields.many2one('ir.model',"Model", required=True),
- 'priority': fields.integer('Server Priority', readonly=True, states={'draft':[('readonly',False)]}, help="Priority between 0 to 10, select define the order of Processing"),
- 'user_id':fields.many2one('res.users', 'User', required=False),
+ ('pop', 'POP Server'),
+ ('imap', 'IMAP Server'),
+ ], 'State', select=True, readonly=False),
+ 'is_ssl':fields.boolean('SSL ?', required=False),
+ 'attach':fields.boolean('Add Attachments ?', required=False),
+ 'date': fields.date('Date', readonly=True, states={'draft':[('readonly', False)]}),
+ 'user' : fields.char('User Name', size=256, required=True, readonly=True, states={'draft':[('readonly', False)]}),
+ 'password' : fields.char('Password', size=1024, invisible=True, required=True, readonly=True, states={'draft':[('readonly', False)]}),
+ 'note': fields.text('Description'),
+ 'action_id':fields.many2one('ir.actions.server', 'Reply Email', required=False, domain="[('state','=','email')]"),
+ 'object_id': fields.many2one('ir.model', "Model", required=True),
+ 'priority': fields.integer('Server Priority', readonly=True, states={'draft':[('readonly', False)]}, help="Priority between 0 to 10, select define the order of Processing"),
+ 'user_id':fields.many2one('res.users', 'User', required=False),
}
_defaults = {
- 'state': lambda *a: "draft",
- 'active': lambda *a: True,
- 'priority': lambda *a: 5,
- 'date': lambda *a: time.strftime('%Y-%m-%d'),
- 'user_id': lambda self, cr, uid, ctx: uid,
+ 'state': lambda *a: "draft",
+ 'active': lambda *a: True,
+ 'priority': lambda *a: 5,
+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
+ 'user_id': lambda self, cr, uid, ctx: uid,
}
-
+
def check_duplicate(self, cr, uid, ids):
vals = self.read(cr, uid, ids, ['user', 'password'])[0]
cr.execute("select count(id) from email_server where user='%s' and password='%s'" % (vals['user'], vals['password']))
@@ -160,201 +77,41 @@ class email_server(osv.osv):
if res:
if res[0] > 1:
return False
- return True
+ return True
_constraints = [
(check_duplicate, 'Warning! Can\'t have duplicate server configuration!', ['user', 'password'])
]
-
+
def onchange_server_type(self, cr, uid, ids, server_type=False, ssl=False):
port = 0
if server_type == 'pop':
port = ssl and 995 or 110
elif server_type == 'imap':
port = ssl and 993 or 143
-
+
return {'value':{'port':port}}
-
- def _process_email(self, cr, uid, server, message, context={}):
- context.update({
- 'server_id':server.id
- })
- history_pool = self.pool.get('mail.server.history')
- msg_txt = email.message_from_string(message)
- message_id = msg_txt.get('Message-ID', False)
-
- msg = {}
- if not message_id:
- return False
-
- fields = msg_txt.keys()
-
- msg['id'] = message_id
- msg['message-id'] = message_id
-
- def _decode_header(txt):
- txt = txt.replace('\r', '')
- return ' '.join(map(lambda (x, y): unicode(x, y or 'ascii'), decode_header(txt)))
-
- if 'Subject' in fields:
- msg['subject'] = _decode_header(msg_txt.get('Subject'))
-
- if 'Content-Type' in fields:
- msg['content-type'] = msg_txt.get('Content-Type')
-
- if 'From' in fields:
- msg['from'] = _decode_header(msg_txt.get('From'))
-
- if 'Delivered-To' in fields:
- msg['to'] = _decode_header(msg_txt.get('Delivered-To'))
-
- if 'Cc' in fields:
- msg['cc'] = _decode_header(msg_txt.get('Cc'))
-
- if 'Reply-To' in fields:
- msg['reply'] = _decode_header(msg_txt.get('Reply-To'))
-
- if 'Date' in fields:
- msg['date'] = msg_txt.get('Date')
-
- if 'Content-Transfer-Encoding' in fields:
- msg['encoding'] = msg_txt.get('Content-Transfer-Encoding')
-
- if 'References' in fields:
- msg['references'] = msg_txt.get('References')
-
- if 'X-openerp-caseid' in fields:
- msg['caseid'] = msg_txt.get('X-openerp-caseid')
-
- if 'X-Priority' in fields:
- msg['priority'] = msg_txt.get('X-priority', '3 (Normal)').split(' ')[0]
-
- if not msg_txt.is_multipart() or 'text/plain' in msg.get('content-type', None):
- encoding = msg_txt.get_content_charset()
- msg['body'] = msg_txt.get_payload(decode=True)
- if encoding:
- msg['body'] = msg['body'].decode(encoding).encode('utf-8')
-
- attachents = {}
- if msg_txt.is_multipart() or 'multipart/alternative' in msg.get('content-type', None):
- body = ""
- counter = 1
- for part in msg_txt.walk():
- if part.get_content_maintype() == 'multipart':
- continue
-
- encoding = part.get_content_charset()
-
- if part.get_content_maintype()=='text':
- content = part.get_payload(decode=True)
- filename = part.get_filename()
- if filename :
- attachents[filename] = content
- else:
- if encoding:
- content = unicode(content, encoding)
- if part.get_content_subtype() == 'html':
- body = html2plaintext(content)
- elif part.get_content_subtype() == 'plain':
- body = content
- elif part.get_content_maintype()=='application' or part.get_content_maintype()=='image' or part.get_content_maintype()=='text':
- filename = part.get_filename();
- if filename :
- attachents[filename] = part.get_payload(decode=True)
- else:
- res = part.get_payload(decode=True)
- if encoding:
- res = res.decode(encoding).encode('utf-8')
-
- body += res
-
- msg['body'] = body
- msg['attachments'] = attachents
-
-
- res_id = False
- if msg.get('references', False):
- id = False
- ref = msg.get('references')
- if '\r\n' in ref:
- ref = msg.get('references').split('\r\n')
- else:
- ref = msg.get('references').split(' ')
-
- if ref:
- hids = history_pool.search(cr, uid, [('name','=',ref[0].strip())])
- if hids:
- id = hids[0]
- history = history_pool.browse(cr, uid, id)
- model_pool = self.pool.get(server.object_id.model)
- context.update({
- 'references_id':ref[0]
- })
- vals = {
-
- }
- if hasattr(model_pool, 'message_update'):
- model_pool.message_update(cr, uid, [history.res_id], vals, msg, context=context)
- else:
- logger.notifyChannel('imap', netsvc.LOG_WARNING, 'method def message_update is not define in model %s' % (model_pool._name))
- return False
- res_id = id
- else:
- model_pool = self.pool.get(server.object_id.model)
- if hasattr(model_pool, 'message_new'):
- res_id = model_pool.message_new(cr, uid, msg, context)
- else:
- logger.notifyChannel('imap', netsvc.LOG_WARNING, 'method def message_new is not define in model %s' % (model_pool._name))
- return False
-
- if server.attach:
- for attactment in attachents or []:
- data_attach = {
- 'name': attactment,
- 'datas':binascii.b2a_base64(str(attachents.get(attactment))),
- 'datas_fname': attactment,
- 'description': 'Mail attachment',
- 'res_model': server.object_id.model,
- 'res_id': res_id,
- }
- self.pool.get('ir.attachment').create(cr, uid, data_attach)
-
- if server.action_id:
- action_pool = self.pool.get('ir.actions.server')
- action_pool.run(cr, uid, [server.action_id.id], {'active_id':res_id, 'active_ids':[res_id]})
-
- res = {
- 'name': message_id,
- 'res_id': res_id,
- 'server_id': server.id,
- 'note': msg.get('body', msg.get('from')),
- 'ref_id':msg.get('references', msg.get('id')),
- 'type':server.type
- }
- his_id = history_pool.create(cr, uid, res)
-
- return res_id
def set_draft(self, cr, uid, ids, context={}):
self.write(cr, uid, ids , {'state':'draft'})
return True
-
+
def button_fetch_mail(self, cr, uid, ids, context={}):
self.fetch_mail(cr, uid, ids)
# sendmail_thread = threading.Thread(target=self.fetch_mail, args=(cr, uid, ids))
# sendmail_thread.start()
return True
-
+
def _fetch_mails(self, cr, uid, ids=False, context={}):
if not ids:
ids = self.search(cr, uid, [])
return self.fetch_mail(cr, uid, ids, context)
-
- def fetch_mail(self, cr, uid, ids, context={}):
+ def fetch_mail(self, cr, uid, ids, context={}):
+ email_tool = self.pool.get('email.server.tools')
for server in self.browse(cr, uid, ids, context):
logger.notifyChannel('imap', netsvc.LOG_INFO, 'fetchmail start checking for new emails on %s' % (server.name))
-
+
count = 0
try:
if server.type == 'imap':
@@ -363,17 +120,21 @@ class email_server(osv.osv):
imap_server = IMAP4_SSL(server.server, int(server.port))
else:
imap_server = IMAP4(server.server, int(server.port))
-
+
imap_server.login(server.user, server.password)
imap_server.select()
result, data = imap_server.search(None, '(UNSEEN)')
for num in data[0].split():
result, data = imap_server.fetch(num, '(RFC822)')
- if self._process_email(cr, uid, server, data[0][1], context):
+ res_id = email_tool.process_email(cr, uid, server.object_id.model, data[0][1], attach=server.attach, server_id=server.id, server_type=server.type, context=context)
+ if res_id and server.action_id:
+ action_pool = self.pool.get('ir.actions.server')
+ action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
+
imap_server.store(num, '+FLAGS', '\\Seen')
- count += 1
+ count += 1
logger.notifyChannel('imap', netsvc.LOG_INFO, 'fetchmail fetch/process %s email(s) from %s' % (count, server.name))
-
+
imap_server.close()
imap_server.logout()
elif server.type == 'pop':
@@ -382,7 +143,7 @@ class email_server(osv.osv):
pop_server = POP3_SSL(server.server, int(server.port))
else:
pop_server = POP3(server.server, int(server.port))
-
+
#TODO: use this to remove only unread messages
#pop_server.user("recent:"+server.user)
pop_server.user(server.user)
@@ -393,79 +154,38 @@ class email_server(osv.osv):
for num in range(1, numMsgs + 1):
(header, msges, octets) = pop_server.retr(num)
msg = '\n'.join(msges)
- self._process_email(cr, uid, server, msg, context)
+ res_id = email_tool.process_email(cr, uid, server.object_id.model, data[0][1], attach=server.attach, server_id=server.id, server_type=server.type, context=context)
+ if res_id and server.action_id:
+ action_pool = self.pool.get('ir.actions.server')
+ action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids':[res_id]})
+
pop_server.dele(num)
pop_server.quit()
-
+
logger.notifyChannel('imap', netsvc.LOG_INFO, 'fetchmail fetch %s email(s) from %s' % (numMsgs, server.name))
-
+
self.write(cr, uid, [server.id], {'state':'done'})
except Exception, e:
logger.notifyChannel(server.type, netsvc.LOG_WARNING, '%s' % (e))
-
+
return True
email_server()
-class mail_server_history(osv.osv):
+class mailgate_message(osv.osv):
+
+ _inherit = "mailgate.message"
- _name = "mail.server.history"
- _description = "Mail Server History"
-
_columns = {
- 'name': fields.char('Message Id', size=256, readonly=True, help="Message Id in Email Server.", select=True),
- 'ref_id': fields.char('Referance Id', size=256, readonly=True, help="Message Id in Email Server.", select=True),
- 'res_id': fields.integer("Resource ID", readonly=True, select=True),
- 'server_id': fields.many2one('email.server',"Mail Server", readonly=True, select=True),
- 'model_id':fields.related('server_id', 'object_id', type='many2one', relation='ir.model', string='Model', readonly=True, select=True),
- 'note': fields.text('Notes', readonly=True),
- 'create_date': fields.datetime('Created Date', readonly=True),
+ 'server_id': fields.many2one('email.server', "Mail Server", readonly=True, select=True),
'type':fields.selection([
- ('pop','POP Server'),
- ('imap','IMAP Server'),
- ],'State', select=True, readonly=True),
+ ('pop', 'POP Server'),
+ ('imap', 'IMAP Server'),
+ ], 'State', select=True, readonly=True),
}
_order = 'id desc'
-
-mail_server_history()
-class fetchmail_tool(osv.osv):
+mailgate_message()
- _name = 'email.server.tools'
- _description = "Email Tools"
- _auto = False
-
- def to_email(self, text):
- _email = re.compile(r'.*<.*@.*\..*>', re.UNICODE)
- def record(path):
- eml = path.group()
- index = eml.index('<')
- eml = eml[index:-1].replace('<','').replace('>','')
- return eml
-
- bits = _email.sub(record, text)
- return bits
-
- def get_partner(self, cr, uid, from_email, context=None):
- """
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks
- @param from_email: email address based on that function will search for the correct
- """
-
- res = {
- 'partner_address_id': False,
- 'partner_id': False
- }
- from_email = self.to_email(from_email)
- address_ids = self.pool.get('res.partner.address').search(cr, uid, [('email', '=', from_email)])
- if address_ids:
- address = self.pool.get('res.partner.address').browse(cr, uid, address_ids[0])
- res['partner_address_id'] = address_ids[0]
- res['partner_id'] = address.partner_id.id
-
- return res
-
-fetchmail_tool()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/fetchmail/fetchmail_view.xml b/addons/fetchmail/fetchmail_view.xml
index 510b31b6131..330f9fec349 100644
--- a/addons/fetchmail/fetchmail_view.xml
+++ b/addons/fetchmail/fetchmail_view.xml
@@ -103,82 +103,54 @@
action="action_email_server_tree_imap"
/>
-
- mail.server.history.tree
- mail.server.history
- tree
-
-
-
-
-
-
-
-
-
-
-
- mail.server.history.form
- mail.server.history
- form
-
-
-
+
+ mailgate.message.tree
+ mailgate.message
+ tree
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ res_model="mailgate.message" src_model="email.server"/>
-
+
Received Email History
- mail.server.history
+ mailgate.message
form
tree,form
-
+
{'type':'imap'}
[('type','=','imap')]
+ id="menu_action_mailgate_message_tree"
+ action="action_mailgate_message_tree"/>
-
+
Received Email History
- mail.server.history
+ mailgate.message
form
tree,form
-
+
{'type':'pop'}
[('type','=','pop')]
+ id="menu_action_mailgate_message_tree_pop"
+ action="action_mailgate_message_tree_pop"/>
diff --git a/addons/fetchmail/security/ir.model.access.csv b/addons/fetchmail/security/ir.model.access.csv
index 907aa187913..7aa6c84d22b 100644
--- a/addons/fetchmail/security/ir.model.access.csv
+++ b/addons/fetchmail/security/ir.model.access.csv
@@ -1,4 +1,2 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_email_server","email.server","model_email_server",,1,1,1,1
-"access_mail_server_history","mail.server.history","model_mail_server_history",,1,1,1,1
-"access_email_server_tools","email.server.tools","model_email_server_tools",,1,1,1,1
diff --git a/addons/hr/i18n/el.po b/addons/hr/i18n/el.po
index 5d965fa1178..0788b8cc952 100644
--- a/addons/hr/i18n/el.po
+++ b/addons/hr/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/hr_contract/i18n/el.po b/addons/hr_contract/i18n/el.po
index afdd0c4c3b8..21a86f08277 100644
--- a/addons/hr_contract/i18n/el.po
+++ b/addons/hr_contract/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/hr_expense/i18n/el.po b/addons/hr_expense/i18n/el.po
index 7ce942b3ff7..549a17a8579 100644
--- a/addons/hr_expense/i18n/el.po
+++ b/addons/hr_expense/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/hr_holidays/i18n/el.po b/addons/hr_holidays/i18n/el.po
index 2d0c0fa2310..3111dc75416 100644
--- a/addons/hr_holidays/i18n/el.po
+++ b/addons/hr_holidays/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index a335e233585..9d6c2cfbbbb 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -21,6 +21,11 @@
from osv import fields, osv
from crm import crm
+import tools
+import collections
+import binascii
+import tools
+from tools.translate import _
AVAILABLE_STATES = [
('draft', 'New'),
@@ -57,11 +62,11 @@ class hr_applicant(osv.osv, crm.crm_case):
_name = "hr.applicant"
_description = "Applicant"
_order = "id desc"
- _inherits = {'mailgate.thread': 'thread_id'}
-
+ _inherit = ['mailgate.thread']
_columns = {
- 'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'name': fields.char('Name', size=128, required=True),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the case without removing it."),
'description': fields.text('Description'),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
@@ -240,6 +245,131 @@ class hr_applicant(osv.osv, crm.crm_case):
context.update({'survey_id': record.survey.id, 'response_id' : [record.response], 'response_no':0, })
value = self.pool.get("survey").action_print_survey(cr, uid, ids, context)
return value
+
+ def message_new(self, cr, uid, msg, context):
+ """
+ Automatically calls when new email message arrives
+
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks
+ """
+
+ mailgate_pool = self.pool.get('email.server.tools')
+
+ subject = msg.get('subject')
+ body = msg.get('body')
+ msg_from = msg.get('from')
+ priority = msg.get('priority')
+
+ vals = {
+ 'name': subject,
+ 'email_from': msg_from,
+ 'email_cc': msg.get('cc'),
+ 'description': body,
+ 'user_id': False,
+ }
+ if msg.get('priority', False):
+ vals['priority'] = priority
+
+ res = mailgate_pool.get_partner(cr, uid, msg.get('from'))
+ if res:
+ vals.update(res)
+ res = self.create(cr, uid, vals, context)
+
+
+ attachents = msg.get('attachments', [])
+ for attactment in attachents or []:
+ data_attach = {
+ 'name': attactment,
+ 'datas':binascii.b2a_base64(str(attachents.get(attactment))),
+ 'datas_fname': attactment,
+ 'description': 'Mail attachment',
+ 'res_model': self._name,
+ 'res_id': res,
+ }
+ self.pool.get('ir.attachment').create(cr, uid, data_attach)
+
+ return res
+
+ def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context={}):
+ """
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of update mail’s IDs
+ """
+
+ if isinstance(ids, (str, int, long)):
+ ids = [ids]
+
+ msg_from = msg['from']
+ vals.update({
+ 'description': msg['body']
+ })
+ if msg.get('priority', False):
+ vals['priority'] = msg.get('priority')
+
+ maps = {
+ 'cost':'planned_cost',
+ 'revenue': 'planned_revenue',
+ 'probability':'probability'
+ }
+ vls = { }
+ for line in msg['body'].split('\n'):
+ line = line.strip()
+ res = tools.misc.command_re.match(line)
+ if res and maps.get(res.group(1).lower(), False):
+ key = maps.get(res.group(1).lower())
+ vls[key] = res.group(2).lower()
+
+ vals.update(vls)
+ res = self.write(cr, uid, ids, vals)
+ return res
+
+ def emails_get(self, cr, uid, ids, context=None):
+
+ """
+ Get Emails
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of email’s IDs
+ @param context: A standard dictionary for contextual values
+ """
+ res = {}
+
+ if isinstance(ids, (str, int, long)):
+ select = [long(ids)]
+ else:
+ select = ids
+
+ for thread in self.browse(cr, uid, select, context=context):
+ values = collections.defaultdict(set)
+
+ for message in thread.message_ids:
+ user_email = (message.user_id and message.user_id.address_id and message.user_id.address_id.email) or False
+ values['user_email'].add(user_email)
+ values['email_from'].add(message.email_from)
+ values['email_cc'].add(message.email_cc or False)
+ values['priority'] = thread.priority
+
+ res[thread.id] = dict((key,list(values[key])) for key, value in values.iteritems())
+
+ return res
+
+ def msg_send(self, cr, uid, id, *args, **argv):
+
+ """ Send The Message
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of email’s IDs
+ @param *args: Return Tuple Value
+ @param **args: Return Dictionary of Keyword Value
+ """
+ return True
+
hr_applicant()
class hr_job(osv.osv):
diff --git a/addons/hr_timesheet_invoice/i18n/es.po b/addons/hr_timesheet_invoice/i18n/es.po
index 3a6afaac4ef..4eed72ce427 100644
--- a/addons/hr_timesheet_invoice/i18n/es.po
+++ b/addons/hr_timesheet_invoice/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: hr_timesheet_invoice
diff --git a/addons/hr_timesheet_sheet/i18n/el.po b/addons/hr_timesheet_sheet/i18n/el.po
index 99558a120ff..ed36280ce80 100644
--- a/addons/hr_timesheet_sheet/i18n/el.po
+++ b/addons/hr_timesheet_sheet/i18n/el.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
diff --git a/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py b/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py
index a5e664c833a..155e40b256b 100644
--- a/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py
+++ b/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py
@@ -106,6 +106,9 @@ class l10n_be_vat_declaration(osv.osv_memory):
data_of_file +='\n\t\t\n\t\t\t'
for item in tax_info:
+ if item['code'] == '91' and ending_month != 12:
+ #the tax code 91 can only be send for the declaration of December
+ continue
if item['code']:
if item['code'] == '71-72':
item['code']='71'
diff --git a/addons/l10n_ch_chart_c2c_pcg/wizard/config.py b/addons/l10n_ch_chart_c2c_pcg/wizard/config.py
index 07ee7a6efe0..dbef21389bf 100644
--- a/addons/l10n_ch_chart_c2c_pcg/wizard/config.py
+++ b/addons/l10n_ch_chart_c2c_pcg/wizard/config.py
@@ -73,7 +73,7 @@ class Tax_template(osv.osv_memory):
def on_change_paid(self, cr, uid, id, tax, account):
return self._on_change(
- cr, uid, ids, tax, vals={'account_paid_id': account})
+ cr, uid, id, tax, vals={'account_paid_id': account})
def execute(self,cr,uid,ids,context={}):
jids = self.pool.get('account.tax.template').search(cr, uid, [])
diff --git a/addons/mail_gateway/mail_gateway.py b/addons/mail_gateway/mail_gateway.py
index 48b3a12aee4..edb723a3ba0 100644
--- a/addons/mail_gateway/mail_gateway.py
+++ b/addons/mail_gateway/mail_gateway.py
@@ -22,7 +22,12 @@
from osv import osv, fields
import time
import tools
+import binascii
+import email
+from email.header import decode_header
import base64
+import re
+from tools.translate import _
class mailgate_thread(osv.osv):
'''
@@ -33,12 +38,24 @@ class mailgate_thread(osv.osv):
_rec_name = 'thread'
_columns = {
- 'thread': fields.char('Thread', size=32, required=False),
- 'message_ids': fields.one2many('mailgate.message', 'thread_id', 'Messages', domain=[('history', '=', True)], required=False),
- 'log_ids': fields.one2many('mailgate.message', 'thread_id', 'Logs', domain=[('history', '=', False)], required=False),
+ 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True)]),
+ 'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False)]),
}
-
- def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=None, context=None):
+
+ def message_new(self, cr, uid, msg, context):
+ raise Exception, _('Method is not implemented')
+
+ def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context={}):
+ raise Exception, _('Method is not implemented')
+
+ def emails_get(self, cr, uid, ids, context=None):
+ raise Exception, _('Method is not implemented')
+
+ def msg_send(self, cr, uid, id, *args, **argv):
+ raise Exception, _('Method is not implemented')
+
+ def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, \
+ email_from=False, message_id=False, references=None, attach=None, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@@ -60,18 +77,16 @@ class mailgate_thread(osv.osv):
if all(isinstance(case_id, (int, long)) for case_id in cases):
cases = self.browse(cr, uid, cases, context=context)
- model_obj = self.pool.get('ir.model')
att_obj = self.pool.get('ir.attachment')
obj = self.pool.get('mailgate.message')
for case in cases:
- model_ids = model_obj.search(cr, uid, [('model', '=', case._name)])
data = {
'name': keyword,
'user_id': uid,
- 'model_id' : model_ids and model_ids[0] or False,
+ 'model' : case._name,
+ 'res_id': case.id,
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
- 'thread_id': case.thread_id.id,
'message_id': message_id,
}
attachments = []
@@ -83,7 +98,7 @@ class mailgate_thread(osv.osv):
'name': subject or 'History',
'history': True,
'user_id': uid,
- 'model_id' : model_ids and model_ids[0] or False,
+ 'model' : case._name,
'res_id': case.id,
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'description': details or (hasattr(case, 'description') and case.description or False),
@@ -94,16 +109,12 @@ class mailgate_thread(osv.osv):
(hasattr(case, 'user_id') and case.user_id and case.user_id.address_id and \
case.user_id.address_id.email) or tools.config.get('email_from', False),
'partner_id': hasattr(case, 'partner_id') and (case.partner_id and case.partner_id.id or False) or False,
- 'thread_id': case.thread_id.id,
+ 'references': references,
'message_id': message_id,
'attachment_ids': [(6, 0, attachments)]
}
res = obj.create(cr, uid, data, context)
return True
-
- __history = history = _history
-
-
mailgate_thread()
class mailgate_message(osv.osv):
@@ -112,22 +123,22 @@ class mailgate_message(osv.osv):
'''
_name = 'mailgate.message'
_description = 'Mailgateway Message'
- _order = 'date desc'
-
+ _order = 'id desc'
_columns = {
'name':fields.char('Message', size=64),
- 'model_id': fields.many2one('ir.model', 'Model'),
+ 'model': fields.char('Object Name', size=128),
'res_id': fields.integer('Resource ID'),
- 'thread_id':fields.many2one('mailgate.thread', 'Thread'),
+ 'ref_id': fields.char('Reference Id', size=256, readonly=True, help="Message Id in Email Server.", select=True),
'date': fields.datetime('Date'),
- 'history': fields.boolean('Is History?', required=False),
+ 'history': fields.boolean('Is History?'),
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
'message': fields.text('Description'),
'email_from': fields.char('Email From', size=84),
'email_to': fields.char('Email To', size=84),
'email_cc': fields.char('Email CC', size=84),
'email_bcc': fields.char('Email BCC', size=84),
- 'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email Server.", select=True),
+ 'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email.", select=True),
+ 'references': fields.text('References', readonly=True, help="Referencess emails."),
'description': fields.text('Description'),
'partner_id': fields.many2one('res.partner', 'Partner', required=False),
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments'),
@@ -135,5 +146,320 @@ class mailgate_message(osv.osv):
mailgate_message()
+class mailgate_tool(osv.osv_memory):
+
+ _name = 'email.server.tools'
+ _description = "Email Server Tools"
+
+ def _to_decode(self, s, charsets):
+ for charset in charsets:
+ if charset:
+ try:
+ return s.decode(charset)
+ except UnicodeError:
+ pass
+ return s.decode('latin1')
+
+ def _decode_header(self, text):
+ if text:
+ text = decode_header(text.replace('\r', ''))
+ return ''.join(map(lambda x:self._to_decode(x[0], [x[1]]), text or []))
+
+ def to_email(self, text):
+ _email = re.compile(r'.*<.*@.*\..*>', re.UNICODE)
+ def record(path):
+ eml = path.group()
+ index = eml.index('<')
+ eml = eml[index:-1].replace('<', '').replace('>', '')
+ return eml
+
+ bits = _email.sub(record, text)
+ return bits
+
+ def history(self, cr, uid, model, res_ids, msg, attach):
+ """This function creates history for mails fetched
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param model: OpenObject Model
+ @param res_ids: Ids of the record of OpenObject model created
+ @param msg: Email details
+ @param attach: Email attachments
+ """
+ if isinstance(res_ids, (int, long)):
+ res_ids = [res_ids]
+
+ msg_pool = self.pool.get('mailgate.message')
+ for res_id in res_ids:
+ msg_data = {
+ 'name': msg.get('subject', 'No subject'),
+ 'date': msg.get('date') ,
+ 'description': msg.get('body', msg.get('from')),
+ 'history': True,
+ 'res_model': model,
+ 'email_cc': msg.get('cc'),
+ 'email_from': msg.get('from'),
+ 'email_to': msg.get('to'),
+ 'message_id': msg.get('message-id'),
+ 'references': msg.get('references'),
+ 'res_id': res_id,
+ 'user_id': uid,
+ 'attachment_ids': [(6, 0, attach)]
+ }
+ msg_id = msg_pool.create(cr, uid, msg_data)
+ return True
+
+ def email_send(self, cr, uid, model, res_id, msg, from_email=False, email_default=False):
+ """This function Sends return email on submission of Fetched email in OpenERP database
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param model: OpenObject Model
+ @param res_id: Id of the record of OpenObject model created from the Email details
+ @param msg: Email details
+ @param email_default: Default Email address in case of any Problem
+ """
+ history_pool = self.pool.get('mailgate.message')
+ model_pool = self.pool.get(model)
+ from_email = from_email or tools.config.get('email_from', None)
+ message = email.message_from_string(str(msg))
+ subject = "[%s] %s" %(res_id, self._decode_header(message['Subject']))
+ #msg_mails = []
+ #mails = [self._decode_header(message['From']), self._decode_header(message['To'])]
+ #mails += self._decode_header(message.get('Cc', '')).split(',')
+
+ values = {}
+ if hasattr(model_pool, 'emails_get'):
+ values = model_pool.emails_get(cr, uid, [res_id])
+ emails = values.get(res_id, {})
+
+ priority = emails.get('priority', [3])[0]
+ em = emails['user_email'] + emails['email_from'] + emails['email_cc']
+ msg_mails = map(self.to_email, filter(None, em))
+
+ #mm = [self._decode_header(message['From']), self._decode_header(message['To'])]
+ #mm += self._decode_header(message.get('Cc', '')).split(',')
+
+ #msg_mails = map(self.to_email, filter(None, mm))
+
+ encoding = message.get_content_charset()
+ message['body'] = message.get_payload(decode=True)
+ if encoding:
+ message['body'] = tools.ustr(message['body'].decode(encoding))
+
+ body = _("""
+Hello %s,
+
+ Your Request ID: %s
+
+Thanks
+
+-------- Original Message --------
+%s
+""") %(self._decode_header(message['From']), res_id, message['body'])
+ res = None
+ try:
+ res = tools.email_send(from_email, msg_mails, subject, body, openobject_id=res_id)
+ except Exception, e:
+ if email_default:
+ temp_msg = '[%s] %s'%(res_id, self._decode_header(message['Subject']))
+ del message['Subject']
+ message['Subject'] = '[OpenERP-FetchError] %s' %(temp_msg)
+ tools.email_send(from_email, email_default, message.get('Subject'), message.get('body'), openobject_id=res_id)
+ return res
+
+ def process_email(self, cr, uid, model, message, attach=True, context=None):
+ """This function Processes email and create record for given OpenERP model
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param model: OpenObject Model
+ @param message: Email details
+ @param attach: Email attachments
+ @param context: A standard dictionary for contextual values"""
+
+ model_pool = self.pool.get(model)
+ if not context:
+ context = {}
+ res_id = False
+ # Create New Record into particular model
+ def create_record(msg):
+ if hasattr(model_pool, 'message_new'):
+ res_id = model_pool.message_new(cr, uid, msg, context)
+ else:
+ data = {
+ 'name': msg.get('subject'),
+ 'email_from': msg.get('from'),
+ 'email_cc': msg.get('cc'),
+ 'user_id': False,
+ 'description': msg.get('body'),
+ 'state' : 'draft',
+ }
+ data.update(self.get_partner(cr, uid, msg.get('from'), context=context))
+ res_id = model_pool.create(cr, uid, data, context=context)
+
+ att_ids = []
+ if attach:
+ for attachment in msg.get('attachments', []):
+ data_attach = {
+ 'name': attachment,
+ 'datas': binascii.b2a_base64(str(attachments.get(attachment))),
+ 'datas_fname': attachment,
+ 'description': 'Mail attachment',
+ 'res_model': model,
+ 'res_id': res_id,
+ }
+ att_ids.append(self.pool.get('ir.attachment').create(cr, uid, data_attach))
+
+ return res_id
+
+ history_pool = self.pool.get('mailgate.message')
+ msg_txt = email.message_from_string(message)
+ message_id = msg_txt.get('Message-ID', False)
+ msg = {}
+ if not message_id:
+ return False
+
+ fields = msg_txt.keys()
+ msg['id'] = message_id
+ msg['message-id'] = message_id
+
+ if 'Subject' in fields:
+ msg['subject'] = self._decode_header(msg_txt.get('Subject'))
+
+ if 'Content-Type' in fields:
+ msg['content-type'] = msg_txt.get('Content-Type')
+
+ if 'From' in fields:
+ msg['from'] = self._decode_header(msg_txt.get('From'))
+
+ if 'Delivered-To' in fields:
+ msg['to'] = self._decode_header(msg_txt.get('Delivered-To'))
+
+ if 'Cc' in fields:
+ msg['cc'] = self._decode_header(msg_txt.get('Cc'))
+
+ if 'Reply-To' in fields:
+ msg['reply'] = self._decode_header(msg_txt.get('Reply-To'))
+
+ if 'Date' in fields:
+ msg['date'] = msg_txt.get('Date')
+
+ if 'Content-Transfer-Encoding' in fields:
+ msg['encoding'] = msg_txt.get('Content-Transfer-Encoding')
+
+ if 'References' in fields:
+ msg['references'] = msg_txt.get('References')
+
+ if 'X-Priority' in fields:
+ msg['priority'] = msg_txt.get('X-priority', '3 (Normal)').split(' ')[0]
+
+ if not msg_txt.is_multipart() or 'text/plain' in msg.get('content-type', None):
+ encoding = msg_txt.get_content_charset()
+ msg['body'] = msg_txt.get_payload(decode=True)
+ if encoding:
+ msg['body'] = tools.ustr(msg['body'])
+
+ attachments = {}
+ if msg_txt.is_multipart() or 'multipart/alternative' in msg.get('content-type', None):
+ body = ""
+ counter = 1
+ for part in msg_txt.walk():
+ if part.get_content_maintype() == 'multipart':
+ continue
+
+ encoding = part.get_content_charset()
+
+ if part.get_content_maintype()=='text':
+ content = part.get_payload(decode=True)
+ filename = part.get_filename()
+ if filename :
+ attachments[filename] = content
+ else:
+ if encoding:
+ content = unicode(content, encoding)
+ if part.get_content_subtype() == 'html':
+ body = tools.html2plaintext(content)
+ elif part.get_content_subtype() == 'plain':
+ body = content
+ elif part.get_content_maintype()=='application' or part.get_content_maintype()=='image' or part.get_content_maintype()=='text':
+ filename = part.get_filename();
+ if filename :
+ attachments[filename] = part.get_payload(decode=True)
+ else:
+ res = part.get_payload(decode=True)
+ if encoding:
+ res = tools.ustr(res)
+
+ body += res
+
+ msg['body'] = body
+ msg['attachments'] = attachments
+ res_ids = []
+ new_res_id = False
+ if msg.get('references', False):
+ references = msg.get('references')
+ if '\r\n' in references:
+ references = msg.get('references').split('\r\n')
+ else:
+ references = msg.get('references').split(' ')
+ for ref in references:
+ ref = ref.strip()
+ res_id = tools.misc.reference_re.search(ref)
+ if res_id:
+ res_id = res_id.group(1)
+ else:
+ res_id = tools.misc.res_re.search(msg['subject'])
+ if res_id:
+ res_id = res_id.group(1)
+ if res_id:
+ res_id = int(res_id)
+ res_ids.append(res_id)
+ model_pool = self.pool.get(model)
+
+ vals = {}
+ if hasattr(model_pool, 'message_update'):
+ model_pool.message_update(cr, uid, [res_id], vals, msg, context=context)
+
+ if not len(res_ids):
+ new_res_id = create_record(msg)
+ res_ids = [new_res_id]
+ # Store messages
+ if hasattr(model_pool, '_history'):
+ model_pool._history(cr, uid, res_ids, _('Receive'), history=True,
+ subject = msg.get('subject'),
+ email = msg.get('to'),
+ details = msg.get('body'),
+ email_from = msg.get('from'),
+ message_id = msg.get('message-id'),
+ references = msg.get('references', False),
+ attach = msg.get('attachments', {}).items(),
+ context = {'model' : model})
+ else:
+ self.history(cr, uid, model, res_ids, msg, att_ids)
+ return new_res_id
+
+ def get_partner(self, cr, uid, from_email, context=None):
+ """This function returns partner Id based on email passed
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks
+ @param from_email: email address based on that function will search for the correct
+ """
+ address_pool = self.pool.get('res.partner.address')
+ res = {
+ 'partner_address_id': False,
+ 'partner_id': False
+ }
+ from_email = self.to_email(from_email)
+ address_ids = address_pool.search(cr, uid, [('email', '=', from_email)])
+ if address_ids:
+ address = address_pool.browse(cr, uid, address_ids[0])
+ res['partner_address_id'] = address_ids[0]
+ res['partner_id'] = address.partner_id.id
+
+ return res
+
+mailgate_tool()
+
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mail_gateway/mail_gateway_view.xml b/addons/mail_gateway/mail_gateway_view.xml
index 7b8ce52cbec..09a24f92772 100644
--- a/addons/mail_gateway/mail_gateway_view.xml
+++ b/addons/mail_gateway/mail_gateway_view.xml
@@ -8,21 +8,28 @@
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -41,8 +48,9 @@
-
-
+
+
+
@@ -53,7 +61,7 @@
search
-
+
@@ -68,28 +76,30 @@
form
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -144,14 +154,47 @@
-
- Mailgateway Threads
- mailgate.thread
+
+
+ Mailgateway Messages
+ mailgate.message
tree,form
form
+ [('history', '=', True)]
+
+
+
+
+ Mailgateway Threads
+ mailgate.thread
+ tree,form
+ form
+
+
+
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
+
+
+ Mailgateway Messages
+ mailgate.message
+ tree,form
+ form
+ [('history', '=', True)]
-
+
tree
@@ -166,7 +209,7 @@
-
-
\ No newline at end of file
+
diff --git a/addons/mail_gateway/scripts/openerp_mailgate/openerp_mailgate.py b/addons/mail_gateway/scripts/openerp_mailgate/openerp_mailgate.py
index c4cad98b046..f294c819c78 100755
--- a/addons/mail_gateway/scripts/openerp_mailgate/openerp_mailgate.py
+++ b/addons/mail_gateway/scripts/openerp_mailgate/openerp_mailgate.py
@@ -21,104 +21,15 @@
#
###########################################################################################
-import re
-import smtplib
-import email
-import mimetypes
-from email.Header import decode_header
-from email.MIMEText import MIMEText
-import xmlrpclib
-import os
-import binascii
-import time
-import socket
import logging
-import sys
import optparse
-
-email_re = re.compile(r"([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6})")
-case_re = re.compile(r"\[([0-9]+)\]", re.UNICODE)
-command_re = re.compile("^Set-([a-z]+) *: *(.+)$", re.I + re.UNICODE)
-reference_re = re.compile("<.*-openobject-(\\d+)@(.*)>", re.UNICODE)
-
-priorities = {
- '1': '1 (Highest)',
- '2': '2 (High)',
- '3': '3 (Normal)',
- '4': '4 (Low)',
- '5': '5 (Lowest)',
-}
-
-def html2plaintext(html, body_id=None, encoding='utf-8'):
- ## (c) Fry-IT, www.fry-it.com, 2007
- ##
- ## download here: http://www.peterbe.com/plog/html2plaintext
-
-
- """ from an HTML text, convert the HTML to plain text.
- If @body_id is provided then this is the tag where the
- body (not necessarily ) starts.
- """
- try:
- from BeautifulSoup import BeautifulSoup, SoupStrainer, Comment
- except:
- return html
-
- urls = []
- if body_id is not None:
- strainer = SoupStrainer(id=body_id)
- else:
- strainer = SoupStrainer('body')
-
- soup = BeautifulSoup(html, parseOnlyThese=strainer, fromEncoding=encoding)
- for link in soup.findAll('a'):
- title = unicode(link)
- for url in [x[1] for x in link.attrs if x[0]=='href']:
- urls.append(dict(url=url, tag=unicode(link), title=title))
-
- html = unicode(soup)
-
- url_index = []
- i = 0
- for d in urls:
- if d['title'] == d['url'] or 'http://'+d['title'] == d['url']:
- html = html.replace(d['tag'], d['url'])
- else:
- i += 1
- html = html.replace(d['tag'], '%s [%s]' % (d['title'], i))
- url_index.append(d['url'])
-
- html = html.replace('', '*').replace(' ', '*')
- html = html.replace('', '*').replace(' ', '*')
- html = html.replace('', '*').replace(' ', '*')
- html = html.replace('', '**').replace(' ', '**')
- html = html.replace('', '**').replace(' ', '**')
- html = html.replace('', '/').replace(' ', '/')
-
- # the only line breaks we respect is those of ending tags and
- # breaks
-
- html = html.replace('\n', ' ')
- html = html.replace(' ', '\n')
- html = html.replace('', '\n')
- html = html.replace('', '\n\n')
- html = re.sub(' ', '\n', html)
- html = html.replace(' ' * 2, ' ')
-
- html = re.sub('<.*?>', ' ', html)
-
- # lstrip all lines
- html = '\n'.join([x.lstrip() for x in html.splitlines()])
-
- for i, url in enumerate(url_index):
- if i == 0:
- html += '\n\n'
- html += '[%s] %s\n' % (i+1, url)
- return html
+import sys
+import xmlrpclib
+import email
class rpc_proxy(object):
- def __init__(self, uid, passwd, host='localhost', port=8069, path='object', dbname='terp'):
- self.rpc = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/%s' % (host, port, path))
+ def __init__(self, uid, passwd, host='localhost', port=8069, path='object', dbname='terp'):
+ self.rpc = xmlrpclib.ServerProxy('http://%s:%s/xmlrpc/%s' % (host, port, path), allow_none=True)
self.user_id = uid
self.passwd = passwd
self.dbname = dbname
@@ -127,7 +38,7 @@ class rpc_proxy(object):
return self.rpc.execute(self.dbname, self.user_id, self.passwd, *request, **kwargs)
class email_parser(object):
- def __init__(self, uid, password, model, email, email_default, dbname, host, port):
+ def __init__(self, uid, password, model, email, email_default, dbname, host, port):
self.rpc = rpc_proxy(uid, password, host=host, port=port, dbname=dbname)
try:
self.model_id = int(model)
@@ -137,301 +48,21 @@ class email_parser(object):
self.model = str(model)
self.email = email
self.email_default = email_default
- self.canal_id = False
-
- def email_get(self, email_from):
- res = email_re.search(email_from)
- return res and res.group(1)
-
- def partner_get(self, email):
- mail = self.email_get(email)
- adr_ids = self.rpc('res.partner.address', 'search', [('email', '=', mail)])
- if not adr_ids:
- return {}
- adr = self.rpc('res.partner.address', 'read', adr_ids, ['partner_id'])
- return {
- 'partner_address_id': adr[0]['id'],
- 'partner_id': adr[0].get('partner_id', False) and adr[0]['partner_id'][0] or False
- }
-
- def _to_decode(self, s, charsets):
- for charset in charsets:
- if charset:
- try:
- return s.decode(charset)
- except UnicodeError:
- pass
- return s.decode('latin1')
-
- def _decode_header(self, text):
- if text:
- text = decode_header(text.replace('\r', ''))
- return ''.join(map(lambda x:self._to_decode(x[0], [x[1]]), text or []))
-
- def msg_new(self, msg):
- message = self.msg_body_get(msg)
- msg_subject = self._decode_header(msg['Subject'])
- msg_from = self._decode_header(msg['From'])
- msg_to = self._decode_header(msg['To'])
- msg_cc = self._decode_header(msg['Cc'] or '')
- data = {
- 'name': msg_subject,
- 'email_from': msg_from,
- 'email_cc': msg_cc,
- 'user_id': False,
- 'description': message['body'],
- 'state' : 'draft',
- }
- data.update(self.partner_get(msg_from))
-
- values = {
- 'message_ids' : [
- (0, 0, {
- 'model_id' : self.rpc('ir.model', 'search', [('name', '=', self.model)])[0],
- 'date' : time.strftime('%Y-%m-%d %H:%M:%S'),
- 'description' : message['body'],
- 'email_from' : msg_from,
- 'email_to' : msg_to,
- 'name' : 'Receive',
- 'history' : True,
- 'user_id' : self.rpc.user_id,
- }
- )
- ]
- }
- thread_id = self.rpc('mailgate.thread', 'create', values)
- data['thread_id'] = thread_id
- oid = self.rpc(self.model, 'create', data)
-
- attachments = message['attachment']
- for attach in attachments or []:
- data_attach = {
- 'name': str(attach),
- 'datas': binascii.b2a_base64(str(attachments[attach])),
- 'datas_fname': str(attach),
- 'description': 'Mail attachment',
- 'res_model': self.model,
- 'res_id': oid
- }
- self.rpc('ir.attachment', 'create', data_attach)
-
- return (oid, thread_id,)
-
- def msg_body_get(self, msg):
- message = {
- 'body' : '',
- 'attachment' : {},
- }
- attachment = message['attachment'];
- counter = 1;
-
- for part in msg.walk():
- if part.get_content_maintype() == 'multipart':
- continue
-
- if part.get_content_maintype()=='text':
- buf = part.get_payload(decode=True)
- if buf:
- txt = self._to_decode(buf, part.get_charsets())
- txt = re.sub("<\/?(\w)>", '', txt)
- if txt and part.get_content_subtype() == 'plain':
- message['body'] += txt
- elif txt and part.get_content_subtype() == 'html':
- message['body'] += html2plaintext(txt)
-
- filename = part.get_filename();
- if filename :
- attachment[filename] = part.get_payload(decode=True);
-
- elif part.get_content_maintype() in ('application', 'image', 'text'):
- filename = part.get_filename();
- if not filename :
- filename = 'attach_file'+str(counter);
- counter += 1;
-
- attachment[filename] = part.get_payload(decode=True);
- message['attachment'] = attachment
- #end for
- return message
-
- def msg_user(self, msg, id):
- body = self.msg_body_get(msg)
-
- # handle email body commands (ex: Set-State: Draft)
- actions = {}
- body_data=''
- for line in body['body'].split('\n'):
- res = command_re.match(line)
- if res:
- actions[res.group(1).lower()] = res.group(2).lower()
- else:
- body_data += line+'\n'
- body['body'] = body_data
-
- data = {
-# 'description': body['body'],
- }
- act = 'case_open'
- if 'state' in actions:
- if actions['state'] in ['draft', 'close', 'cancel', 'open', 'pending']:
- act = 'case_' + actions['state']
-
- for k1, k2 in [('cost', 'planned_cost'), ('revenue', 'planned_revenue'), ('probability', 'probability')]:
- try:
- data[k2] = float(actions[k1])
- except:
- pass
-
- if 'priority' in actions:
- if actions['priority'] in ('1', '2', '3', '4', '5'):
- data['priority'] = actions['priority']
-
- if 'partner' in actions:
- data['email_from'] = actions['partner'][:128]
-
- if 'user' in actions:
- uids = self.rpc('res.users', 'name_search', actions['user'])
- if uids:
- data['user_id'] = uids[0][0]
-
- self.rpc(self.model, act, [id])
- self.rpc(self.model, 'write', [id], data)
- attachments = body['attachment']
- for attach in attachments or []:
- data_attach = {
- 'name': str(attach),
- 'datas': binascii.b2a_base64(str(attachments[attach])),
- 'datas_fname': str(attach),
- 'description': 'Mail attachment',
- 'res_model': self.model,
- 'res_id': id
- }
- self.rpc('ir.attachment', 'create', data_attach)
-
- self.create_message(id, msg['From'], msg['To'], 'Send', message['body'])
-
- return id
-
- def create_message(self, oid, email_from, email_to, name, body):
- """
- This functions creates a message in the thread
-
- > create_message(id, msg['From'], msg['To'], 'Send', message['body'])
- """
- values = {
- 'thread_id' : self.rpc(self.model, 'read', [oid], ['thread_id'])[0]['thread_id'][0],
- 'model_id' : self.rpc('ir.model', 'search', [('name', '=', self.model)])[0],
- 'res_id' : oid,
- 'date' : time.strftime('%Y-%m-%d %H:%M:%S'),
- 'description' : body,
- 'email_from' : self._decode_header(email_from),
- 'email_to' : self._decode_header(email_to),
- 'name' : name,
- 'history' : True,
- 'user_id' : self.rpc.user_id,
- }
- return self.rpc('mailgate.message', 'create', values)
-
- def msg_send(self, msg, emails, priority=None):
- if not emails:
- return False
-
- msg['To'] = emails[0]
- if len(emails) > 1:
- msg['Cc'] = ','.join(emails[1:])
- msg['Reply-To'] = self.email
-
- if priority:
- msg['X-Priority'] = priorities.get(priority, '3 (Normal)')
-
- s = smtplib.SMTP()
- s.connect()
- s.sendmail(self.email, emails, msg.as_string())
- s.close()
- return True
-
- def msg_partner(self, msg, id):
- message = self.msg_body_get(msg)
- body = message['body']
- act = 'case_open'
- self.rpc(self.model, act, [id])
- attachments = message['attachment']
- for attach in attachments or []:
- data_attach = {
- 'name': str(attach),
- 'datas': binascii.b2a_base64(str(attachments[attach])),
- 'datas_fname': str(attach),
- 'description': 'Mail attachment',
- 'res_model': self.model,
- 'res_id': id
- }
- self.rpc('ir.attachment', 'create', data_attach)
-
- self.create_message(id, msg['From'], msg['To'], 'Send', message['body'])
- return id
-
- def msg_test(self, msg, case_str):
- if not case_str:
- return (False, False)
- case_id = int(case_str)
- emails = self.rpc(self.model, 'emails_get', [case_id])
- return (case_id, emails)
+
- def parse(self, msg):
- case_str = reference_re.search(msg.get('References', ''))
- if case_str:
- case_str = case_str.group(1)
- else:
- case_str = case_re.search(msg.get('Subject', ''))
- if case_str:
- case_str = case_str.group(1)
-
- logging.info("email: %s -> %s -- %s", msg['From'], self.email, msg['Subject'])
- (case_id, emails) = self.msg_test(msg, case_str)
- thread_id = None
- if case_id:
- values = self.rpc(self.model, 'read', [case_id], ['thread_id'])
- if values:
- thread_id = values[0]['thread_id'][0]
- emails = emails[str(thread_id)]
-
- user_email = filter(None, emails['user_email'])[0]
-
- if user_email and self.email_get(user_email) == self.email_get(self._decode_header(msg['From'])):
- self.msg_user(msg, case_id)
- else:
- self.msg_partner(msg, case_id)
- else:
- case_id, thread_id = self.msg_new(msg)
- subject = self._decode_header(msg['Subject'])
- msg['Subject'] = "[%s] %s" % (case_id, subject,)
- msg['Message-Id'] = "<%s-openerpcrm-%s@%s>" % (time.time(), case_id, socket.gethostname(),)
-
- logging.info(" case: %r", case_id)
- logging.info(" thread: %r", thread_id)
-
- values = self.rpc(self.model, 'emails_get', [case_id])
-
- emails = values[str(thread_id)]
-
- priority = emails.get('piority', [3])[0]
- em = emails['user_email'] + emails['email_from'] + emails['email_cc']
- emails = map(self.email_get, filter(None, em))
-
- mm = [self._decode_header(msg['From']), self._decode_header(msg['To'])]+self._decode_header(msg.get('Cc', '')).split(',')
- msg_mails = map(self.email_get, filter(None, mm))
-
- emails = filter(lambda m: m and m not in msg_mails, emails)
+ def parse(self, message):
try:
- self.msg_send(msg, emails, priority)
- except:
- if self.email_default:
- a = self._decode_header(msg['Subject'])
- msg['Subject'] = '[OpenERP-CaseError] ' + a
- self.msg_send(msg, self.email_default.split(','))
- return case_id, thread_id, emails
+ res_id = self.rpc('email.server.tools', 'process_email', self.model, message)
+ except Exception, e:
+ res_id = False
+
+# Reply mail
+ if res_id:
+ self.rpc('email.server.tools', 'email_send', self.model, res_id, message, self.email, self.email_default)
+
+ return res_id
if __name__ == '__main__':
parser = optparse.OptionParser(usage='usage: %prog [options]', version='%prog v1.0')
@@ -454,7 +85,7 @@ if __name__ == '__main__':
parser = email_parser(options.userid, options.password, options.model, options.email, options.default, dbname=options.dbname, host=options.host, port=options.port)
- msg_txt = email.message_from_file(sys.stdin)
+ msg_txt = sys.stdin.read()
parser.parse(msg_txt)
diff --git a/addons/marketing_campaign/__openerp__.py b/addons/marketing_campaign/__openerp__.py
index 8abbf9eb706..16e45a36c96 100644
--- a/addons/marketing_campaign/__openerp__.py
+++ b/addons/marketing_campaign/__openerp__.py
@@ -28,9 +28,15 @@
"document",
"email_template"
],
- "author" : "Tiny",
+ "author" : "OpenERP SA",
"category": 'Generic Modules/Marketing',
"description": """
+Allows you to setup leads automation through marketing campaigns. The campaigns
+are dynamic and multi-channels. The process:
+* Design marketing campaigns that incluces mail templates, reports to print,
+ miscelleanous actions, etc.
+* Define segments that are selections of target people
+* Launch your campaign to automate communications.
""",
'website': 'http://www.openerp.com',
'init_xml': [],
diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py
index feeaa074b6d..386e5639dd7 100644
--- a/addons/marketing_campaign/marketing_campaign.py
+++ b/addons/marketing_campaign/marketing_campaign.py
@@ -73,11 +73,19 @@ you required for the campaign"),
campaign = self.browse(cr, uid, ids[0])
if not campaign.activity_ids :
raise osv.except_osv("Error", "There is no activitity in the campaign")
- act_ids = [ act_id.id for act_id in campaign.activity_ids]
- act_ids = self.pool.get('marketing.campaign.activity').search(cr, uid,
- [('id', 'in', act_ids), ('start', '=', True)])
+ actvity_ids = [ act_id.id for act_id in campaign.activity_ids]
+ act_obj = self.pool.get('marketing.campaign.activity')
+ act_ids = act_obj.search(cr, uid, [('id', 'in', actvity_ids),
+ ('start', '=', True)])
if not act_ids :
raise osv.except_osv("Error", "There is no starting activitity in the campaign")
+ act_ids = act_obj.search(cr, uid, [('id', 'in', actvity_ids),
+ ('type', '=', 'email')])
+ for activity in act_obj.browse(cr, uid, act_ids):
+ if not activity.email_template_id.enforce_from_account :
+ raise osv.except_osv("Error", "Campaign cannot be start : Email Account is missing in email activity")
+ if activity.email_template_id.enforce_from_account.state != 'approved' :
+ raise osv.except_osv("Error", "Campaign cannot be start : Email Account is not approved for email activity")
self.write(cr, uid, ids, {'state': 'running'})
return True
@@ -239,7 +247,7 @@ class marketing_campaign_activity(osv.osv):
def __init__(self, *args):
self._actions = {'paper' : self.process_wi_report,
'email' : self.process_wi_email,
- 'server_action' : self.process_wi_action,
+ 'action' : self.process_wi_action,
}
return super(marketing_campaign_activity, self).__init__(*args)
@@ -273,13 +281,15 @@ class marketing_campaign_activity(osv.osv):
return True
def process_wi_email(self, cr, uid, activity, workitem, context=None):
- return self.pool.get('email.template').generate_mail(cr, uid, activity.email_template_id.id, [workitem.res_id], context=context)
+ return self.pool.get('email.template').generate_mail(cr, uid,
+ activity.email_template_id.id,
+ [workitem.res_id], context=context)
def process_wi_action(self, cr, uid, activity, workitem, context={}):
context = {}
server_obj = self.pool.get('ir.actions.server')
- server_obj.run(cr, uid, [activity.server_action_id.id], context)
- return True
+ context['active_id'] = workitem.res_id
+ return server_obj.run(cr, uid, [activity.server_action_id.id], context)
def process(self, cr, uid, act_id, wi_id, context={}):
activity = self.browse(cr, uid, act_id)
@@ -339,7 +349,7 @@ class marketing_campaign_workitem(osv.osv):
type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
type='many2one', relation='ir.model', string='Object', select=1),
- 'res_id': fields.integer('Resource ID', select=1),
+ 'res_id': fields.integer('Resource ID', select=1, readonly=1),
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64),
'date': fields.datetime('Execution Date'),
'partner_id': fields.many2one('res.partner', 'Partner', select=1),
@@ -408,7 +418,7 @@ class marketing_campaign_workitem(osv.osv):
else:
vals = {'state': 'exception'}
if type(result) == type({}) and 'error_msg' in result:
- vals['error_msg'] = result['error_msg']
+ vals['error_msg'] = result['error_msg']
self.write(cr, uid, wi.id, vals)
else:
self.write(cr, uid, wi.id, {'state': 'cancelled'})
diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml
index f8dfc003369..62cb4a9cf50 100644
--- a/addons/marketing_campaign/marketing_campaign_view.xml
+++ b/addons/marketing_campaign/marketing_campaign_view.xml
@@ -28,6 +28,7 @@
+
@@ -44,7 +45,7 @@
-
+
@@ -366,6 +367,7 @@
+
@@ -449,7 +451,7 @@
{'group_by': [], 'search_default_todo': 1}
-
+
=%s and date<=%s''', (line.user_id.i
for line in self.browse(cr, uid, ids, context):
where = ''
if line.user_id:
- where='user_id='+str(line.user_id.id)+' and '
+ where = 'user_id=' + str(line.user_id.id) + ' and '
cr.execute('''select
sum(planned_hours)
from
project_task
where
- '''+where+'''
+ ''' + where + '''
project_id in (select id from project_project where category_id=%s) and
date_close>=%s and
date_close<=%s''', (
diff --git a/addons/project_timesheet/i18n/es.po b/addons/project_timesheet/i18n/es.po
index 777b9212e77..0ab5c2a38c1 100644
--- a/addons/project_timesheet/i18n/es.po
+++ b/addons/project_timesheet/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: project_timesheet
diff --git a/addons/report_analytic_planning/i18n/es.po b/addons/report_analytic_planning/i18n/es.po
index bf4ebb8ce76..c26f1f6dcd5 100644
--- a/addons/report_analytic_planning/i18n/es.po
+++ b/addons/report_analytic_planning/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_analytic_planning
diff --git a/addons/report_task/i18n/es.po b/addons/report_task/i18n/es.po
index 8bb396c5454..0f0a57fb957 100644
--- a/addons/report_task/i18n/es.po
+++ b/addons/report_task/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_task
diff --git a/addons/sale/board_sale_view.xml b/addons/sale/board_sale_view.xml
index c89b90ecb65..2f290ce5dd8 100644
--- a/addons/sale/board_sale_view.xml
+++ b/addons/sale/board_sale_view.xml
@@ -30,11 +30,11 @@
-
-
+
+
-
+
diff --git a/addons/sale/i18n/es.po b/addons/sale/i18n/es.po
index 3c481e1f885..1ac3b8b4117 100644
--- a/addons/sale/i18n/es.po
+++ b/addons/sale/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: sale
diff --git a/addons/sale/report/sale_report_view.xml b/addons/sale/report/sale_report_view.xml
index e2fd3ae54e8..ae948f66b76 100644
--- a/addons/sale/report/sale_report_view.xml
+++ b/addons/sale/report/sale_report_view.xml
@@ -50,41 +50,41 @@
search
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
+
+
+
@@ -103,7 +103,7 @@
-
+
@@ -171,7 +171,7 @@
[('state','in',('manual','progress')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
-
+
graph
@@ -213,7 +213,7 @@
sale.report
form
graph,tree
- [('state','in',('manual','progress')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
+ [('state','in',('manual','progress','done')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
@@ -233,7 +233,7 @@
sale.report
tree
-
+
@@ -245,61 +245,79 @@
sale.report
graph
-
+
-
- Sold product and Total Price
+
+ Sales by Products
sale.report
form
graph,tree
- [('state','in',('manual','progress')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
+ [('state','in',('manual','progress','done')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
graph
-
+
tree
-
+
-
- sales.category.product.price.tree
- sale.report
- tree
-
-
-
-
-
-
-
-
- Total Price By Product Category
- sale.report
- form
- tree
- [('state','in',('manual','progress')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
-
+
+ view.sales.by.month.tree
+ sale.report
+ tree
+
+
+
+
+
+
+
+
+
+ Sales By Month
+ sale.report
+ form
+ tree,graph
+ [('state','in',('manual','progress','done')),('year','=', time.strftime('%Y'))]
+ {'group_by_no_leaf':1,'group_by':['month','product_id']}
+
+
+ sale.top.quotations.tree
+ sale.order
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
- Quotation For Sale
+ Top Quotations
sale.order
form
tree,form
- [('state','=','draft'),('date_order','<=', time.strftime('%Y-%m-%d')),('date_order','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]
-
+ [('state','=','draft')]
+
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index f18f142b061..b7229fcef46 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -204,7 +204,8 @@ class sale_order(osv.osv):
return result.keys()
_columns = {
- 'name': fields.char('Order Reference', size=64, required=True, select=True),
+ 'name': fields.char('Order Reference', size=64, required=True,
+ readonly=True, states={'draft': [('readonly', False)]}, select=True),
'shop_id': fields.many2one('sale.shop', 'Shop', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'origin': fields.char('Source document', size=64, help="Reference of the document that generated this sale order request."),
'client_order_ref': fields.char('Customer Reference', size=64),
diff --git a/addons/stock/i18n/es.po b/addons/stock/i18n/es.po
index 4b8113738fd..02fbad114bd 100644
--- a/addons/stock/i18n/es.po
+++ b/addons/stock/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:46+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: stock
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 0393cef5634..16646440685 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -535,10 +535,10 @@ class stock_picking(osv.osv):
seq_obj_name = 'stock.picking.' + vals['type']
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
type_list = {
- 'out':_('Packing List'),
+ 'out':_('Picking List'),
'in':_('Reception'),
- 'internal': _('Internal picking'),
- 'delivery': _('Delivery order')
+ 'internal': _('Internal Picking'),
+ 'delivery': _('Delivery Order')
}
new_id = super(stock_picking, self).create(cr, user, vals, context)
if not vals.get('auto_picking', False):
@@ -709,7 +709,7 @@ class stock_picking(osv.osv):
"""
for pick in self.browse(cr, uid, ids, context=context):
type_list = {
- 'out':'Packing List',
+ 'out':'Picking List',
'in':'Reception',
'internal': 'Internal picking',
'delivery': 'Delivery order'
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 46db1e03c4b..0129fbe8b8d 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -1132,7 +1132,7 @@
- Outgoing Packings
+ Outgoing Orders
stock.picking
ir.actions.act_window
form
diff --git a/addons/stock_location/i18n/es.po b/addons/stock_location/i18n/es.po
index 70f2d3a33cd..20249109ac1 100644
--- a/addons/stock_location/i18n/es.po
+++ b/addons/stock_location/i18n/es.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2010-06-24 03:47+0000\n"
+"X-Launchpad-Export-Date: 2010-06-25 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: stock_location