[MERGE] merge from trunk addons
bzr revid: mra@mra-laptop-20100625041328-8rymp929ui5rg5hb
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
</separator>
|
||||
<xpath expr="//label[@string='description']"
|
||||
position="attributes">
|
||||
<attribute name="string">You can enhance OpenERP's basic accounting support with a few additional OpenERP applications.</attribute>
|
||||
<attribute name="string">From this screen, you can configure your accounting system. Choose a Chart of Account matched to your accounting system or the Generic Chart of Account which allows you to configure which suit your needs.</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//button[@string='Install Modules']" position="attributes">
|
||||
<attribute name="string">Configure</attribute>
|
||||
|
||||
@@ -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\'"'
|
||||
|
||||
|
||||
@@ -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) "
|
||||
"<jesteve@zikzakmedia.com>\n"
|
||||
"PO-Revision-Date: 2010-06-24 10:03+0000\n"
|
||||
"Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\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
|
||||
|
||||
@@ -8,13 +8,13 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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) <borjals@pexego.es>\n"
|
||||
"Language-Team: Galician <gl@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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) <borjals@pexego.es>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 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 :"
|
||||
@@ -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
|
||||
|
||||
+98
-89
@@ -8,13 +8,13 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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 <Unknown>\n"
|
||||
"Language-Team: Greek <el@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 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
|
||||
|
||||
@@ -8,13 +8,13 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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 <Unknown>\n"
|
||||
"Language-Team: Greek <el@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 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 "Διαγραφή αρχείων καταγραφής"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
<xpath expr="//label[@string='description']"
|
||||
position="attributes">
|
||||
<attribute name="string"
|
||||
>Now that OpenERP is installed, We have selected applications commonly useful to users which you can install directly, as well as sets of applications for more specific types or groups of businesses (the vertical modules).
|
||||
|
||||
If you don't think you need any of these right now, you can easily install them later on.</attribute>
|
||||
>The most common applications have been pre selected. You can directly install them. You can either choose generic modules, or select modules for specific business sectors and industries. If you do not think you need any of these right now, you can easily install them later.</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//separator[@string="vsep"]' position='attributes'>
|
||||
<attribute name='string'></attribute>
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="name" required="True"/><field name="account_no"/>
|
||||
<field name="currency" widget="selection"/><field name="street"/>
|
||||
<field name="zip"/>
|
||||
<field name="street2"/>
|
||||
<field name="country_id"/>
|
||||
<field name="zip"/>
|
||||
<field name="state_id"/>
|
||||
<field name="city"/>
|
||||
<field name="email"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<attribute name="string">Contact Information</attribute>
|
||||
</form>
|
||||
<xpath expr="//label[@string='description']" position="attributes">
|
||||
<attribute name="string">Information about you and the company you are related too. The Basic information related to the company has already been collected and some more information required by you to fill.</attribute>
|
||||
<attribute name="string">To receive more information, please fill in the form about you and your company. Documentation and/or information will be sent to you as soon as possible.</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//separator[@string="title"]' position='attributes'>
|
||||
<attribute name='string'>Would you like more information or documentation ?</attribute>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
##############################################################################
|
||||
|
||||
import crm
|
||||
import crm_mailgate
|
||||
import crm_action_rule
|
||||
import crm_segmentation
|
||||
import crm_meeting
|
||||
|
||||
@@ -25,26 +25,25 @@
|
||||
<xpath expr="//button[@string='Install Modules']" position="attributes">
|
||||
<attribute name="string">Configure</attribute>
|
||||
</xpath>
|
||||
<group colspan="8">
|
||||
<group colspan="8">
|
||||
<group colspan="4" col="4" groups="base.group_extended" name="other">
|
||||
<field name="crm_claim" />
|
||||
<field name="crm_helpdesk" />
|
||||
<field name="crm_fundraising" />
|
||||
<field name="wiki_sale_faq"/>
|
||||
<field name="sale_crm" invisible="1"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Synchronization" colspan="4" />
|
||||
<field name="crm_caldav" />
|
||||
<field name="fetchmail" />
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Plugins" colspan="4" />
|
||||
<separator string="Plugins" colspan="4" />
|
||||
<field name="thunderbird" />
|
||||
<label string="*Outlook*" />
|
||||
<!-- TODO <field name="outlook" />-->
|
||||
</group>
|
||||
<group colspan="4" col="4" groups="base.group_extended" name="other">
|
||||
<separator string="Additional features" colspan="4" />
|
||||
<field name="crm_claim" />
|
||||
<field name="crm_helpdesk" />
|
||||
<field name="crm_fundraising" />
|
||||
<field name="wiki_sale_faq"/>
|
||||
<field name="sale_crm" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</data>
|
||||
</field>
|
||||
|
||||
+133
-2
@@ -27,6 +27,9 @@ 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 """
|
||||
@@ -117,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'),
|
||||
@@ -139,8 +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),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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 = {
|
||||
@@ -148,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],
|
||||
@@ -231,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:
|
||||
|
||||
@@ -146,6 +146,11 @@
|
||||
<field name="date_open"/>
|
||||
<field name="date_closed"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Mailings" colspan="2" col="2"/>
|
||||
<field name="optin"/>
|
||||
<field name="optout"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Statistics" colspan="2" col="2"/>
|
||||
<field name="day_open"/>
|
||||
@@ -256,12 +261,11 @@
|
||||
<field name="type">calendar</field>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="arch" type="xml">
|
||||
<calendar string="Meeting For Leads Generation"
|
||||
date_start="create_date" color="user_id"
|
||||
date_delay="duration">
|
||||
<calendar string="Leads Generation"
|
||||
date_start="create_date" color="user_id">
|
||||
<field name="name" />
|
||||
<field name="partner_name" />
|
||||
<field name="partner_contact" />
|
||||
<field name="partner_address_id" />
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
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()
|
||||
@@ -148,6 +148,7 @@
|
||||
<button string="Invite People"
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
icon="terp-partner" type="action"
|
||||
attrs="{'readonly': [('state', '=', 'done')]}"
|
||||
context="{'model' : 'crm.meeting', 'attendee_field':'attendee_ids'}" colspan="2"/>
|
||||
<field name="attendee_ids" colspan="4"
|
||||
nolabel="1" widget="one2many" mode="tree,form">
|
||||
@@ -214,10 +215,27 @@
|
||||
<tree string="Meetings"
|
||||
colors="red:state=='open';black:state in ('draft', 'cancel','done','pending')">
|
||||
<field name="name" string="Subject" />
|
||||
<field name="partner_id" string="Partner" />
|
||||
<field name="date" string="Meeting Date" />
|
||||
<field name="date" string="Start Date" />
|
||||
<field name="duration" />
|
||||
<field name="partner_id" string="Partner" />
|
||||
<field name="location" />
|
||||
<field name="categ_id" string="Meeting Type"/>
|
||||
<field name="class" string="Privacy"/>
|
||||
<field name="state"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="show_as" invisible="1" string="Show time as"/>
|
||||
<button name="case_reset" string="Reset to Unconfirmed"
|
||||
states="open,done,cancel" type="object"
|
||||
icon="gtk-convert" />
|
||||
<button name="case_open" string="Confirm"
|
||||
states="draft" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_close" string="Done"
|
||||
states="open" type="object"
|
||||
icon="gtk-jump-to" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open" type="object"
|
||||
icon="gtk-cancel" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -268,6 +286,10 @@
|
||||
help="Current Meetings"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1" string="Subject"/>
|
||||
<field name="categ_id" select="1"
|
||||
string="Meeting Type" widget="selection"
|
||||
domain="[('object_id.model', '=', 'crm.meeting')]" />
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_id" select="1" />
|
||||
<field name="section_id" select="1" widget="selection">
|
||||
<filter icon="terp-personal+"
|
||||
@@ -282,16 +304,26 @@
|
||||
domain="[]" context="{'group_by':'date'}" />
|
||||
<filter string="Privacy" icon="terp-locked"
|
||||
domain="[]" context="{'group_by':'class'}" />
|
||||
<filter string="Show time as" icon="terp-project"
|
||||
domain="[]" context="{'group_by':'show_as'}" />
|
||||
<separator orientation="vertical" />
|
||||
<filter string="Responsible" icon="terp-personal" domain="[]"
|
||||
context="{'group_by':'user_id'}" />
|
||||
<filter string="Partner" icon="terp-personal" domain="[]"
|
||||
context="{'group_by':'partner_id'}" />
|
||||
<separator orientation="vertical" />
|
||||
<filter string="Meeting Type" help="Meeting Type"
|
||||
icon="terp-stock_symbol-selection" domain="[]"
|
||||
context="{'group_by':'categ_id'}" />
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
|
||||
context="{'group_by':'state'}" />
|
||||
<separator orientation="vertical" />
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Extended Options...">
|
||||
<field name="class" select="1" string="Privacy"/>
|
||||
<field name="show_as" string="Show time as" select="1"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
<act_window
|
||||
@@ -19,7 +19,7 @@
|
||||
src_model="crm.lead"
|
||||
view_mode="tree,form,calendar,"
|
||||
context="{'default_duration': 4.0, 'default_opportunity_id': active_id}"
|
||||
domain="[('user_id','=',uid), ('opportunity_id', '=', active_id)]"
|
||||
domain="[('opportunity_id', '=', active_id)]"
|
||||
view_type="form"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="crm_case_category_act_oppor11">
|
||||
|
||||
@@ -258,6 +258,8 @@
|
||||
<field name="section_id"
|
||||
invisible="context.get('invisible_section', True)" />
|
||||
<field name="user_id"/>
|
||||
<field name="priority" invisible="1"/>
|
||||
<field name="categ_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
@@ -299,14 +301,14 @@
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Opportunities">
|
||||
<filter icon="terp-check"
|
||||
string="Current"
|
||||
string="Current" help="Current Opportunities"
|
||||
name="current"
|
||||
domain="[('state','in',('draft','open'))]"/>
|
||||
<filter icon="terp-camera_test"
|
||||
string="Open"
|
||||
string="Open" help="Open Opportunities"
|
||||
domain="[('state','=','open')]"/>
|
||||
<filter icon="terp-gtk-media-pause"
|
||||
string="Pending"
|
||||
string="Pending" help="Pending Opportunities"
|
||||
domain="[('state','=','pending')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-today" string="Today"
|
||||
@@ -352,8 +354,10 @@
|
||||
<separator orientation="vertical" />
|
||||
<filter string="Creation" icon="terp-go-month"
|
||||
domain="[]" context="{'group_by':'create_date'}" />
|
||||
<filter string="Exp.Closing" icon="terp-go-month"
|
||||
domain="[]" context="{'group_by':'date_deadline'}" />
|
||||
<filter string="Exp.Closing"
|
||||
icon="terp-go-month"
|
||||
help="Expected Closing" domain="[]"
|
||||
context="{'group_by':'date_deadline'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -82,8 +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),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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 = {
|
||||
|
||||
@@ -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: crm
|
||||
|
||||
@@ -147,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 res_id=c.id and res_model='crm.lead') 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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -9,13 +9,15 @@
|
||||
<field name="model">crm.opportunity2phonecall</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Schedule Other Call">
|
||||
<form string="Schedule a PhoneCall">
|
||||
<separator string="Schedule a PhoneCall" colspan="4"/>
|
||||
<group colspan="2" >
|
||||
<field name="name"/>
|
||||
<field name="date" string="Planned Date"/>
|
||||
<newline/>
|
||||
<field name="user_id" />
|
||||
<field name="section_id"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<label string ="" colspan="2"/>
|
||||
<button name="action_cancel" string="_Cancel"
|
||||
icon="gtk-cancel" special="cancel" />
|
||||
|
||||
@@ -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
|
||||
@@ -88,8 +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),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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()
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Claims" colors="blue:state=='pending';black:state=='open';grey:state in ('close', 'cancel')">
|
||||
<field name="id"/>
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id" />
|
||||
@@ -67,6 +66,8 @@
|
||||
<field name="date_deadline" string="Deadline"/>
|
||||
<field name="date_closed" string="Closure Date"/>
|
||||
<field name="categ_id" string="Type" select="1"/>
|
||||
<field name="stage_id" invisible="1"/>
|
||||
<field name="som" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
@@ -123,8 +124,9 @@
|
||||
<field name="user_id" string="Responsible"/>
|
||||
<field name="section_id" widget="selection"/>
|
||||
<label string="Stage: " align="1.0"/>
|
||||
<group colspan="1" col="2">
|
||||
<group colspan="1" col="3">
|
||||
<field name="stage_id" select="1" nolabel="1"/>
|
||||
<button name="stage_previous" string="" type="object" icon="gtk-go-back" />
|
||||
<button icon="gtk-go-forward" string="" name="stage_next" type="object"/>
|
||||
</group>
|
||||
<field name="categ_id" select="1" widget="selection"
|
||||
@@ -143,18 +145,18 @@
|
||||
<separator colspan="4" string=""/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" select="1"/>
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-jump-to" />
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_pending" string="Pending"
|
||||
states="draft,open" type="object"
|
||||
icon="gtk-media-pause" />
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-jump-to" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_reset"
|
||||
string="Reset to Draft" states="done,cancel"
|
||||
type="object" icon="gtk-convert" />
|
||||
@@ -291,12 +293,37 @@
|
||||
widget="selection"/>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Partner" icon="terp-partner"
|
||||
domain="[]" help="Partner"
|
||||
context="{'group_by':'partner_id'}" />
|
||||
<filter string="Responsible" icon="terp-personal"
|
||||
domain="[]" help="Responsible User"
|
||||
context="{'group_by':'user_id'}" />
|
||||
<filter string="Sales Team" icon="terp-personal+"
|
||||
domain="[]" help="Sales Team"
|
||||
context="{'group_by':'section_id'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Stage" icon="terp-stage"
|
||||
domain="[]" context="{'group_by':'stage_id'}" />
|
||||
<filter string="Type" icon="terp-stock_symbol-selection"
|
||||
domain="[]" context="{'group_by':'categ_id'}" />
|
||||
<filter string="State"
|
||||
icon="terp-stock_effects-object-colorize"
|
||||
domain="[]" context="{'group_by':'state'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Claim Date" icon="terp-go-month"
|
||||
domain="[]" help="Claim Date"
|
||||
context="{'group_by':'date'}" />
|
||||
<filter string="Deadline" icon="terp-go-month"
|
||||
domain="[]"
|
||||
context="{'group_by':'date_deadline'}" />
|
||||
<filter string="Closure" icon="terp-go-month"
|
||||
domain="[]"
|
||||
domain="[]" help="Date Closed"
|
||||
context="{'group_by':'date_closed'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="State of Mind"
|
||||
icon="terp-face-plain"
|
||||
domain="[]" context="{'group_by':'som'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -85,8 +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),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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 = {
|
||||
|
||||
@@ -72,21 +72,21 @@
|
||||
<field name="user_id" />
|
||||
<field name="state" />
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_pending" string="Pending"
|
||||
states="draft,open" type="object" icon="gtk-media-pause" />
|
||||
<button name="case_escalate" string="Escalate"
|
||||
states="open,draft,pending" type="object"
|
||||
groups="base.group_extended"
|
||||
icon="gtk-go-up" />
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_reset" string="Reset to Draft"
|
||||
states="done,cancel" type="object" icon="gtk-convert" />
|
||||
</tree>
|
||||
@@ -133,15 +133,9 @@
|
||||
<separator colspan="4"/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state"/>
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_pending" string="Pending"
|
||||
states="draft,open" type="object"
|
||||
icon="gtk-media-pause" />
|
||||
@@ -149,6 +143,12 @@
|
||||
states="open,draft,pending" type="object"
|
||||
groups="base.group_extended"
|
||||
icon="gtk-go-up" />
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_reset"
|
||||
string="Reset to Draft" states="done,cancel"
|
||||
type="object" icon="gtk-convert" />
|
||||
@@ -304,9 +304,15 @@
|
||||
domain="[]"
|
||||
context="{'group_by':'user_id'}" />
|
||||
<separator orientation="vertical" />
|
||||
<filter string="Type" icon="terp-stock_symbol-selection"
|
||||
domain="[]"
|
||||
<filter string="Category" help="Fund Category"
|
||||
icon="terp-stock_symbol-selection" domain="[]"
|
||||
context="{'group_by':'categ_id'}" />
|
||||
<filter string="Payment Mode" help="Payment Mode"
|
||||
icon="terp-dolar" domain="[]"
|
||||
context="{'group_by':'type_id'}" />
|
||||
<separator orientation="vertical" />
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
|
||||
context="{'group_by':'state'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -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 """
|
||||
@@ -85,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],
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Helpdesk Support">
|
||||
<group colspan="4" col="7">
|
||||
<field name="name" select="1"/>
|
||||
<field name="name" select="1" string="Query"/>
|
||||
<field name="section_id" widget="selection"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<button name="remind_user"
|
||||
@@ -71,26 +71,26 @@
|
||||
<separator colspan="4"/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" select="1"/>
|
||||
<button name="case_close"
|
||||
states="open,draft,pending" string="Close"
|
||||
type="object" icon="gtk-close" />
|
||||
<button name="case_open"
|
||||
states="draft,pending" string="Open"
|
||||
type="object" icon="gtk-go-forward" />
|
||||
<button name="case_cancel"
|
||||
states="draft,open,pending" string="Cancel"
|
||||
type="object" icon="gtk-cancel" />
|
||||
states="draft,pending" string="Open"
|
||||
type="object" icon="gtk-go-forward" />
|
||||
<button name="case_pending"
|
||||
states="draft,open" string="Pending"
|
||||
type="object" icon="gtk-media-pause" />
|
||||
states="draft,open" string="Pending"
|
||||
type="object" icon="gtk-media-pause" />
|
||||
<button name="case_escalate"
|
||||
states="open,draft,pending"
|
||||
string="Escalate" type="object"
|
||||
icon="gtk-go-up" />
|
||||
states="open,draft,pending"
|
||||
string="Escalate" type="object"
|
||||
icon="gtk-go-up" />
|
||||
<button name="case_close"
|
||||
states="open,draft,pending" string="Close"
|
||||
type="object" icon="gtk-jump-to" />
|
||||
<button name="case_cancel"
|
||||
states="draft,open,pending" string="Cancel"
|
||||
type="object" icon="gtk-cancel" />
|
||||
<button name="case_reset"
|
||||
states="done,cancel"
|
||||
string="Reset to Draft" type="object"
|
||||
icon="gtk-convert" />
|
||||
states="done,cancel"
|
||||
string="Reset to Draft" type="object"
|
||||
icon="gtk-convert" />
|
||||
</group>
|
||||
</page>
|
||||
<page string="History" groups="base.group_extended">
|
||||
@@ -179,24 +179,18 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Helpdesk Support Tree"
|
||||
colors="black:state=='open';blue:state=='pending';grey:state in ('cancel','close')">
|
||||
<field name="id"/>
|
||||
<field name="name" string="Query Description" />
|
||||
<field name="name" string="Query" />
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="date" string="Date"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
<field name="priority"/>
|
||||
<field name="som" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_pending" string="Pending"
|
||||
states="draft,open" type="object"
|
||||
icon="gtk-media-pause" />
|
||||
@@ -204,6 +198,12 @@
|
||||
groups="base.group_extended"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-go-up" />
|
||||
<button name="case_close" string="Done"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-close" />
|
||||
<button name="case_cancel" string="Cancel"
|
||||
states="draft,open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_reset" string="Reset to Draft"
|
||||
states="done,cancel" type="object" icon="gtk-convert" />
|
||||
</tree>
|
||||
@@ -255,12 +255,30 @@
|
||||
</field>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Customer" icon="terp-personal"
|
||||
domain="[]" context="{'group_by':'partner_id'}" />
|
||||
<filter string="Partner" icon="terp-partner"
|
||||
domain="[]" help="Partner"
|
||||
context="{'group_by':'partner_id'}" />
|
||||
<filter string="Responsible" icon="terp-personal"
|
||||
domain="[]" help="Responsible User"
|
||||
context="{'group_by':'user_id'}" />
|
||||
<filter string="Sales Team" icon="terp-personal+"
|
||||
domain="[]" help="Sales Team"
|
||||
context="{'group_by':'section_id'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
|
||||
context="{'group_by':'state'}" />
|
||||
<filter string="Priority" icon="terp-rating-rated"
|
||||
domain="[]" context="{'group_by':'priority'}" />
|
||||
<filter string="State of Mind"
|
||||
icon="terp-face-plain"
|
||||
domain="[]" context="{'group_by':'som'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Date" icon="terp-go-month"
|
||||
domain="[]" help="Request Date"
|
||||
context="{'group_by':'date'}" />
|
||||
<filter string="Deadline" icon="terp-go-month"
|
||||
domain="[]"
|
||||
context="{'group_by':'date_deadline'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -108,8 +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(which are approved).",
|
||||
domain=[('state','=','approved')]),
|
||||
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(
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -56,14 +56,16 @@
|
||||
<field name="model_int_name" invisible="1" />
|
||||
<notebook colspan="4">
|
||||
<page string="Mail Details">
|
||||
<field name="enforce_from_account" required= "1"/>
|
||||
<group col="4" colspan="2">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Addresses" colspan="2"/>
|
||||
<field name="from_email"/>
|
||||
<field name="def_to" colspan="4" required="1" />
|
||||
<field name="def_cc" colspan="4" />
|
||||
<field name="def_bcc" colspan="4" />
|
||||
<field name="def_to" required="1"/>
|
||||
<field name="def_cc"/>
|
||||
<field name="def_bcc"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Email Data" colspan="2"/>
|
||||
<field name="enforce_from_account" required= "1"/>
|
||||
<field name="def_subject" colspan="4" required="1" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<field name="lang" colspan="4" />
|
||||
|
||||
@@ -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 <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\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 <Unknown>\n"
|
||||
"Language-Team: Greek <el@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 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 "Διαχείριση εργασιών"
|
||||
@@ -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
|
||||
|
||||
+65
-345
@@ -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
|
||||
## <peter@fry-it.com>
|
||||
## 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 <body>) 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('<strong>','*').replace('</strong>','*')
|
||||
html = html.replace('<b>','*').replace('</b>','*')
|
||||
html = html.replace('<h3>','*').replace('</h3>','*')
|
||||
html = html.replace('<h2>','**').replace('</h2>','**')
|
||||
html = html.replace('<h1>','**').replace('</h1>','**')
|
||||
html = html.replace('<em>','/').replace('</em>','/')
|
||||
|
||||
# the only line breaks we respect is those of ending tags and
|
||||
# breaks
|
||||
|
||||
html = html.replace('\n',' ')
|
||||
html = html.replace('<br>', '\n')
|
||||
html = html.replace('<tr>', '\n')
|
||||
html = html.replace('</p>', '\n\n')
|
||||
html = re.sub('<br\s*/>', '\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:
|
||||
|
||||
@@ -103,82 +103,54 @@
|
||||
action="action_email_server_tree_imap"
|
||||
/>
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_server_history_tree">
|
||||
<field name="name">mail.server.history.tree</field>
|
||||
<field name="model">mail.server.history</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Received Mail History">
|
||||
<field name="server_id" select="1"/>
|
||||
<field name="create_date" select="1"/>
|
||||
<field name="model_id"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="ref_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_email_server_history_form">
|
||||
<field name="name">mail.server.history.form</field>
|
||||
<field name="model">mail.server.history</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email History">
|
||||
<group col="6" colspan="4">
|
||||
<record model="ir.ui.view" id="mailgate_message_tree_view">
|
||||
<field name="name">mailgate.message.tree</field>
|
||||
<field name="model">mailgate.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="inherit_id" ref="mail_gateway.view_mailgate_message_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="server_id" select="1"/>
|
||||
<field name="create_date" select="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Resource Information" colspan="2"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="res_id"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Meta Information" colspan="2"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="ref_id"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="note" colspan="4" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
context="{'server_id': active_id}"
|
||||
domain="[('server_id', '=', active_id)]"
|
||||
id="act_server_history" name="Email History"
|
||||
res_model="mail.server.history" src_model="email.server"/>
|
||||
res_model="mailgate.message" src_model="email.server"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_server_history_tree">
|
||||
<record model="ir.actions.act_window" id="action_mailgate_message_tree">
|
||||
<field name="name">Received Email History</field>
|
||||
<field name="res_model">mail.server.history</field>
|
||||
<field name="res_model">mailgate.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_mail_server_history_tree"/>
|
||||
<field name="view_id" ref="mailgate_message_tree_view"/>
|
||||
<field name="context">{'type':'imap'}</field>
|
||||
<field name="domain">[('type','=','imap')]</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_action_email_server_tree_imap"
|
||||
id="menu_action_email_server_history_tree"
|
||||
action="action_email_server_history_tree"/>
|
||||
id="menu_action_mailgate_message_tree"
|
||||
action="action_mailgate_message_tree"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_server_history_tree_pop">
|
||||
<record model="ir.actions.act_window" id="action_mailgate_message_tree_pop">
|
||||
<field name="name">Received Email History</field>
|
||||
<field name="res_model">mail.server.history</field>
|
||||
<field name="res_model">mailgate.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_mail_server_history_tree"/>
|
||||
<field name="view_id" ref="mailgate_message_tree_view"/>
|
||||
<field name="context">{'type':'pop'}</field>
|
||||
<field name="domain">[('type','=','pop')]</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_action_email_server_tree"
|
||||
id="menu_action_email_server_history_tree_pop"
|
||||
action="action_email_server_history_tree_pop"/>
|
||||
id="menu_action_mailgate_message_tree_pop"
|
||||
action="action_mailgate_message_tree_pop"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'),
|
||||
@@ -60,8 +65,8 @@ class hr_applicant(osv.osv, crm.crm_case):
|
||||
_inherit = ['mailgate.thread']
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -27,6 +27,7 @@ import email
|
||||
from email.header import decode_header
|
||||
import base64
|
||||
import re
|
||||
from tools.translate import _
|
||||
|
||||
class mailgate_thread(osv.osv):
|
||||
'''
|
||||
@@ -37,14 +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', 'res_id', 'Messages', domain=[('history', '=', True)], readonly=True),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False)], readonly=True),
|
||||
'model': fields.char('Model Name', size=64, required=False),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
}
|
||||
|
||||
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):
|
||||
'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 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,
|
||||
@@ -98,6 +109,7 @@ 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,
|
||||
'references': references,
|
||||
'message_id': message_id,
|
||||
'attachment_ids': [(6, 0, attachments)]
|
||||
}
|
||||
@@ -125,7 +137,8 @@ class mailgate_message(osv.osv):
|
||||
'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'),
|
||||
@@ -133,3 +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()
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<field name="message_id" />
|
||||
<field name="ref_id" />
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
@@ -76,28 +76,30 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailgateway Thread">
|
||||
<field name="thread" select="1"/>
|
||||
<group col="6" colspan="4">
|
||||
<field name="thread" select="1" colspan="3"/>
|
||||
</group>
|
||||
<separator string="Logs" colspan="4"/>
|
||||
<field name="log_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
|
||||
<tree string="Mailgateway Logs">
|
||||
<field name="name" select="1" />
|
||||
<field name="date" />
|
||||
</tree>
|
||||
<form string="Mailgate Logs">
|
||||
<field name="name" />
|
||||
<field name="date" />
|
||||
<field name="user_id" />
|
||||
<field name="message_id" />
|
||||
<notebook colspan="4">
|
||||
<page string="Email Details">
|
||||
<group col="4" colspan="4">
|
||||
<separator string="Email Details" colspan="4"/>
|
||||
<field name="email_from" />
|
||||
<field name="email_to" />
|
||||
<field name="email_cc" />
|
||||
<field name="email_bcc" />
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<tree string="Mailgateway Logs">
|
||||
<field name="name" select="1" />
|
||||
<field name="date" />
|
||||
</tree>
|
||||
<form string="Mailgate Logs">
|
||||
<field name="name" />
|
||||
<field name="date" />
|
||||
<field name="user_id" />
|
||||
<field name="message_id" />
|
||||
<notebook colspan="4">
|
||||
<page string="Email Details">
|
||||
<group col="4" colspan="4">
|
||||
<separator string="Email Details" colspan="4"/>
|
||||
<field name="email_from" />
|
||||
<field name="email_to" />
|
||||
<field name="email_cc" />
|
||||
<field name="email_bcc" />
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
@@ -163,10 +165,33 @@
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_view_mailgate_thread">
|
||||
<field name="name">Mailgateway Threads</field>
|
||||
<field name="res_model">mailgate.thread</field>
|
||||
<field name="name">Mailgateway Threads</field>
|
||||
<field name="res_model">mailgate.thread</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
<field name="act_window_id" ref="action_view_mailgate_thread"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_view_mailgate_thread_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_form"/>
|
||||
<field name="act_window_id" ref="action_view_mailgate_thread"/>
|
||||
</record>
|
||||
|
||||
<!-- Mailgateway message action-->
|
||||
<record model="ir.actions.act_window" id="action_view_mailgate_message">
|
||||
<field name="name">Mailgateway Messages</field>
|
||||
<field name="res_model">mailgate.message</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="domain">[('history', '=', True)]</field>
|
||||
<field name="view_id" ref="view_mailgate_thread_tree"/>
|
||||
</record>
|
||||
|
||||
@@ -195,4 +220,4 @@
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
||||
@@ -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
|
||||
## <peter@fry-it.com>
|
||||
## 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 <body>) 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('<strong>', '*').replace('</strong>', '*')
|
||||
html = html.replace('<b>', '*').replace('</b>', '*')
|
||||
html = html.replace('<h3>', '*').replace('</h3>', '*')
|
||||
html = html.replace('<h2>', '**').replace('</h2>', '**')
|
||||
html = html.replace('<h1>', '**').replace('</h1>', '**')
|
||||
html = html.replace('<em>', '/').replace('</em>', '/')
|
||||
|
||||
# the only line breaks we respect is those of ending tags and
|
||||
# breaks
|
||||
|
||||
html = html.replace('\n', ' ')
|
||||
html = html.replace('<br>', '\n')
|
||||
html = html.replace('<tr>', '\n')
|
||||
html = html.replace('</p>', '\n\n')
|
||||
html = re.sub('<br\s*/>', '\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
|
||||
@@ -130,296 +41,28 @@ class email_parser(object):
|
||||
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)
|
||||
self.model = str(model)
|
||||
except:
|
||||
self.model_id = self.rpc('ir.model', 'search', [('model', '=', model)])[0]
|
||||
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, {
|
||||
'res_model' : self.model,
|
||||
'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,
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
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, )
|
||||
|
||||
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 = {
|
||||
'res_model' : self.model,
|
||||
'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)
|
||||
if case_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 = 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)
|
||||
|
||||
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, 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')
|
||||
@@ -442,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)
|
||||
|
||||
|
||||
@@ -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': [],
|
||||
|
||||
@@ -79,7 +79,7 @@ you required for the campaign"),
|
||||
('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_idsf),
|
||||
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 :
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
<field name="context">{'group_by': [], 'search_default_todo': 1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_action_marketing_campaign_workitem" parent="menu_marketing_campaign" action="action_marketing_campaign_workitem" sequence="30" groups="base.group_extended"/>
|
||||
<menuitem id="menu_action_marketing_campaign_workitem" parent="menu_marketing_campaign" action="action_marketing_campaign_workitem" sequence="30"/>
|
||||
|
||||
<act_window name="All Segments"
|
||||
res_model="marketing.campaign.segment"
|
||||
|
||||
@@ -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"
|
||||
|
||||
#. module: mrp
|
||||
|
||||
@@ -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: mrp_operations
|
||||
|
||||
@@ -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: olap
|
||||
|
||||
@@ -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: point_of_sale
|
||||
|
||||
@@ -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: project
|
||||
|
||||
@@ -31,6 +31,9 @@ from crm import crm
|
||||
from osv import fields,osv,orm
|
||||
from osv.orm import except_orm
|
||||
from tools.translate import _
|
||||
import collections
|
||||
import binascii
|
||||
import tools
|
||||
|
||||
class project_issue(osv.osv, crm.crm_case):
|
||||
_name = "project.issue"
|
||||
@@ -178,8 +181,8 @@ class project_issue(osv.osv, crm.crm_case):
|
||||
method=True, multi='working_days_open', type="float", store=True),
|
||||
'working_hours_close': fields.function(_compute_day, string='Working Hours to Close the Issue', \
|
||||
method=True, multi='working_days_close', type="float", store=True),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('res_model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('res_model','=',_name)]),
|
||||
'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)]),
|
||||
}
|
||||
|
||||
def _get_project(self, cr, uid, context):
|
||||
@@ -299,5 +302,129 @@ class project_issue(osv.osv, crm.crm_case):
|
||||
self.write(cr, uid, [case.id], data)
|
||||
return True
|
||||
|
||||
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
|
||||
|
||||
project_issue()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -50,41 +50,41 @@
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Sales Analysis">
|
||||
<group>
|
||||
<filter icon="terp-go-year" string=" 365 Days "
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks performed in last 365 days"/>
|
||||
<filter icon="terp-go-month" string=" 30 Days "
|
||||
name="month"
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks performed in last 30 days"/>
|
||||
<filter icon="terp-go-week"
|
||||
string=" 7 Days "
|
||||
separator="1"
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks during last 7 days"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-document-new"
|
||||
string="Quotations"
|
||||
domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-dolar"
|
||||
string="Sales"
|
||||
domain="[('state','not in',('draft','done','cancel'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-sale"
|
||||
string="Picked"
|
||||
domain="[('shipped','=',True)]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_id"/>
|
||||
<group>
|
||||
<filter icon="terp-go-year" string=" 365 Days "
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks performed in last 365 days"/>
|
||||
<filter icon="terp-go-month" string=" 30 Days "
|
||||
name="month"
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks performed in last 30 days"/>
|
||||
<filter icon="terp-go-week"
|
||||
string=" 7 Days "
|
||||
separator="1"
|
||||
domain="[('date','<=', time.strftime('%%Y-%%m-%%d')), ('date','>',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Tasks during last 7 days"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-document-new"
|
||||
string="Quotations"
|
||||
domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-dolar"
|
||||
string="Sales"
|
||||
domain="[('state','not in',('draft','done','cancel'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-sale"
|
||||
string="Picked"
|
||||
domain="[('shipped','=',True)]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="user_id" widget="selection">
|
||||
<filter icon="terp-personal"
|
||||
<field name="user_id" widget="selection">
|
||||
<filter icon="terp-personal"
|
||||
string="My Sales"
|
||||
help="My Sales"
|
||||
domain="[('user_id','=',uid)]"/>
|
||||
</field>
|
||||
</group>
|
||||
<newline/>
|
||||
</field>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="1" string="Group By..." colspan="10" col="12">
|
||||
<filter string="Salesman" icon="terp-personal" name="User" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/>
|
||||
@@ -103,7 +103,7 @@
|
||||
<filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
|
||||
<filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<newline/>
|
||||
<group expand="0" string="Extended options..." groups="base.group_extended">
|
||||
<field name="date"/>
|
||||
<field name="date_confirm"/>
|
||||
@@ -171,7 +171,7 @@
|
||||
<field name="domain">[('state','in',('manual','progress')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="view_id" ref="view_sales_by_partner_graph"/>
|
||||
</record>
|
||||
<record id="open_view_sales_by_partner_graph" model="ir.actions.act_window.view">
|
||||
<record id="open_view_sales_by_partner_graph" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="view_id" ref="view_sales_by_partner_graph"/>
|
||||
@@ -233,7 +233,7 @@
|
||||
<field name="model">sale.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sold products and Total Price">
|
||||
<tree string="Sales by Products">
|
||||
<field name="product_id"/>
|
||||
<field name="price_total"/>
|
||||
</tree>
|
||||
@@ -245,7 +245,7 @@
|
||||
<field name="model">sale.report</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Sold products and Total Price" type="bar">
|
||||
<graph string="Sales by Products" type="bar">
|
||||
<field name="product_id" />
|
||||
<field name="price_total" operator="+"/>
|
||||
</graph>
|
||||
@@ -253,11 +253,11 @@
|
||||
</record>
|
||||
|
||||
<record id="action_sales_product_total_price" model="ir.actions.act_window">
|
||||
<field name="name">Sold product and Total Price</field>
|
||||
<field name="name">Sales by Products</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree</field>
|
||||
<field name="domain">[('state','in',('manual','progress','done')),('date','<=', time.strftime('%Y-%m-%d')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="domain">[('state','in',('manual','progress','done')),('date','>',(datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="view_id" ref="view_sales_product_total_price_graph"/>
|
||||
</record>
|
||||
<record id="open_view_sales_product_total_price_graph" model="ir.actions.act_window.view">
|
||||
@@ -273,29 +273,29 @@
|
||||
<field name="act_window_id" ref="action_sales_product_total_price"/>
|
||||
</record>
|
||||
|
||||
<record id="view_sales_by_month_tree" model="ir.ui.view">
|
||||
<field name="name">view.sales.by.month.tree</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Total Sales By Month">
|
||||
<field name="month" />
|
||||
<field name="price_total" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_sales_by_month" model="ir.actions.act_window">
|
||||
<field name="name">Sales By Month</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('state','in',('manual','progress','done')),('year','=', time.strftime('%Y'))]</field>
|
||||
<field name="context">{'group_by_no_leaf':1,'group_by':['month']}</field>
|
||||
<field name="view_id" ref="view_sales_by_month_tree"/>
|
||||
<field name="search_view_id" ref="view_order_product_search"/>
|
||||
</record>
|
||||
<record id="view_sales_by_month_tree" model="ir.ui.view">
|
||||
<field name="name">view.sales.by.month.tree</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sales By Month">
|
||||
<field name="month" />
|
||||
<field name="product_id" />
|
||||
<field name="price_total" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_sales_by_month" model="ir.actions.act_window">
|
||||
<field name="name">Sales By Month</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="domain">[('state','in',('manual','progress','done')),('year','=', time.strftime('%Y'))]</field>
|
||||
<field name="context">{'group_by_no_leaf':1,'group_by':['month','product_id']}</field>
|
||||
<field name="view_id" ref="view_sales_by_month_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="view_top_quotations_tree" model="ir.ui.view">
|
||||
<record id="view_top_quotations_tree" model="ir.ui.view">
|
||||
<field name="name">sale.top.quotations.tree</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="type">tree</field>
|
||||
@@ -317,7 +317,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state','=','draft')]</field>
|
||||
<field name="view_id" ref="view_top_quotations_tree"/>
|
||||
<field name="view_id" ref="view_top_quotations_tree"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -1132,7 +1132,7 @@
|
||||
</record>
|
||||
|
||||
<record id="action_picking_tree" model="ir.actions.act_window">
|
||||
<field name="name">Outgoing Packings</field>
|
||||
<field name="name">Outgoing Orders</field>
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<xpath expr="//label[@string='description']" position="attributes">
|
||||
<attribute name="string">This module is required for the thuderbird plug-in to work properly.This allows you to select an object that you had like to add to your email and its attachments. You can select a partner, a task, a project, an analytical account, or any other object and attach selected mail as .eml file in attachment of selected record.</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//button[@string='Install Modules']" position="attributes">
|
||||
<attribute name="string">Configure</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//separator[@string="vsep"]' position='attributes'>
|
||||
<attribute name='string'></attribute>
|
||||
<attribute name='rowspan'>15</attribute>
|
||||
|
||||
Reference in New Issue
Block a user