[MERGE]: Merged with team1 branch.

bzr revid: uco@tinyerp.com-20100611051439-2miynuot8etuwc3o
This commit is contained in:
uco (OpenERP)
2010-06-11 10:44:39 +05:30
46 changed files with 944 additions and 847 deletions
+3 -3
View File
@@ -7,13 +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-03 20:09+0000\n"
"PO-Revision-Date: 2010-06-09 15:10+0000\n"
"Last-Translator: Ferdinand @ ChriCar <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-04 03:45+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -4904,7 +4904,7 @@ msgstr "Details Finanzkonto"
#. module: account
#: rml:account.overdue:0
msgid "VAT:"
msgstr "USt.:"
msgstr "UID:"
#. module: account
#: rml:account.analytic.account.cost_ledger:0
+4 -4
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.6\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2010-05-29 11:45+0000\n"
"Last-Translator: digitalsatori <Unknown>\n"
"PO-Revision-Date: 2010-06-09 16:41+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\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-05-30 03:44+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -712,7 +712,7 @@ msgstr "客户欠款金额合计"
#. module: account
#: view:account.move.line:0
msgid "St."
msgstr ""
msgstr "结单编码"
#. module: account
#: model:ir.actions.act_window,name:account.action_tax_code_line_open
+1 -1
View File
@@ -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-09 03:35+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_analytic_analysis
+1 -1
View File
@@ -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-09 03:36+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_anglo_saxon
+22 -3
View File
@@ -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-09 03:21+0000\n"
"PO-Revision-Date: 2010-06-09 03:36+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-09 03:35+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_balance
@@ -117,6 +117,25 @@ msgid ""
" 5. You have an option to print the desired report in Landscape format.\n"
" "
msgstr ""
"Το κομμάτι Ισολογισμών είναι ένα επιπρόσθετο λειτουργικό κομμάτι στο κομμάτι "
"της Οικονομικής Διαχείρισης\n"
"\n"
" Αυτό το κομμάτι σου δίνει διάφορες επιλογές για εκτύπωση ισολογισμών.\n"
"\n"
" 1. Μπορείς να συγκρίνεις τους ισολογισμούς διαφόρων ετών.\n"
"\n"
" 2. Μπορείς να ορίσεις την απόλυτη ή επί τοις εκατό σύγκριση μεταξύ δύο "
"ετών.\n"
"\n"
" 3. Μπορείς να ορίσεις το ισολογισμό αναφοράς για την επί τοις εκατό "
"σύγκριση συγκεκριμένων ετών.\n"
"\n"
" 4. Μπορείς να επιλέξεις περιόδους ως πραγματική ημερομηνία ή περιόδους "
"ως ημέρα δημιουργίας.\n"
"\n"
" 5. Έχεις δυνατότητα να εκτυπώσεις την επιθυμητή αναφορά σε μορφή "
"Landscape.\n"
" "
#. module: account_balance
#: wizard_view:account.balance.account.balance.report,backtoinit:0
@@ -149,7 +168,7 @@ msgstr "Σύνολο:"
#: rml:account.account.balance.landscape:0
#: rml:account.balance.account.balance:0
msgid "Account Balance -"
msgstr ""
msgstr "Ισολογισμός"
#. module: account_balance
#: wizard_field:account.balance.account.balance.report,init,format_perc:0
+1 -1
View File
@@ -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-09 03:36+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_coda
+1 -1
View File
@@ -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-09 03:35+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_invoice_layout
+4 -4
View File
@@ -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: 2009-09-08 15:11+0000\n"
"Last-Translator: Makis Nicolaou <mark.nicolaou@gmail.com>\n"
"PO-Revision-Date: 2010-06-09 06:03+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-04-17 04:11+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_payment
@@ -40,7 +40,7 @@ msgstr "Επιλέξτε την Κατάσταση Πληρωμής που θα
#. module: account_payment
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr ""
msgstr "Λανθασμένο όνομα μοντέλου στον ορισμό ενέργειας"
#. module: account_payment
#: view:payment.line:0
+4 -4
View File
@@ -8,19 +8,19 @@ 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-03-17 14:08+0000\n"
"Last-Translator: 英华 <wantinghard@gmail.com>\n"
"PO-Revision-Date: 2010-06-09 16:41+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: Simplified Chinese <zh_CN@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-04-17 04:20+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_module_quality
#: field:module.quality.check,final_score:0
msgid "Final Score (%)"
msgstr ""
msgstr "最终评分(%)"
#. module: base_module_quality
#: constraint:ir.model:0
+51 -52
View File
@@ -30,19 +30,19 @@ from tools.translate import _
MAX_LEVEL = 15
AVAILABLE_STATES = [
('draft', 'Draft'),
('open', 'Open'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('draft', 'Draft'),
('open', 'Open'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('pending', 'Pending'),
]
AVAILABLE_PRIORITIES = [
('1', 'Highest'),
('2', 'High'),
('3', 'Normal'),
('4', 'Low'),
('5', 'Lowest'),
('2', 'High'),
('3', 'Normal'),
('4', 'Low'),
('5', 'Lowest'),
]
class crm_case(object):
@@ -107,10 +107,10 @@ class crm_case(object):
"""
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.context_section_id.id or False
def stage_next(self, cr, uid, ids, context=None):
"""This function computes next stage for case from its current stage
using available stage for that case type
using available stage for that case type
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@@ -120,8 +120,8 @@ class crm_case(object):
context = {}
s = self.get_stage_dict(cr, uid, ids, context=context)
section = self._name
for case in self.browse(cr, uid, ids, context):
section = (case.section_id.id or False)
if section in s:
st = case.stage_id.id or False
if st in s[section]:
@@ -137,13 +137,13 @@ class crm_case(object):
@param context: A standard dictionary for contextual values"""
if not context:
context = {}
sid = self.pool.get('crm.case.stage').search(cr, uid, \
stage_obj = self.pool.get('crm.case.stage')
sid = stage_obj.search(cr, uid, \
[('object_id.model', '=', self._name)], context=context)
s = {}
previous = {}
for stage in self.pool.get('crm.case.stage').browse(cr, uid, sid, context=context):
section = stage.section_id.id or False
section = self._name
for stage in stage_obj.browse(cr, uid, sid, context=context):
s.setdefault(section, {})
s[section][previous.get(section, False)] = stage.id
previous[section] = stage.id
@@ -151,7 +151,7 @@ class crm_case(object):
def stage_previous(self, cr, uid, ids, context=None):
"""This function computes previous stage for case from its current stage
using available stage for that case type
using available stage for that case type
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@@ -161,9 +161,8 @@ class crm_case(object):
context = {}
s = self.get_stage_dict(cr, uid, ids, context=context)
section = self._name
for case in self.browse(cr, uid, ids, context):
section = (case.section_id.id or False)
if section in s:
st = case.stage_id.id or False
s[section] = dict([(v, k) for (k, v) in s[section].iteritems()])
@@ -178,11 +177,11 @@ class crm_case(object):
@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
@email: Partner's email ID
"""
if not part:
return {'value': {'partner_address_id': False,
'email_from': False,
return {'value': {'partner_address_id': False,
'email_from': False,
}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
data = {'partner_address_id': addr['contact']}
@@ -196,13 +195,13 @@ class crm_case(object):
@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
@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}}
def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context={}):
mailgate_pool = self.pool.get('mailgate.thread')
return mailgate_pool._history(cr, uid, cases, keyword, history=history,\
@@ -210,7 +209,7 @@ class crm_case(object):
details=details, email_from=email_from,\
message_id=message_id, attach=attach, \
context=context)
def case_open(self, cr, uid, ids, *args):
"""Opens Case
@param self: The object pointer
@@ -266,7 +265,7 @@ class crm_case(object):
if case.section_id.parent_id.user_id:
data['user_id'] = case.section_id.parent_id.user_id.id
else:
raise osv.except_osv(_('Error !'), _('You can not escalate this case.\nYou are already at the top level.'))
raise osv.except_osv(_('Error !'), _('You can not escalate, You are already at the top level regarding your sales-team category.'))
self.write(cr, uid, [case.id], data)
cases = self.browse(cr, uid, ids)
self._history(cr, uid, cases, _('Escalate'))
@@ -318,7 +317,7 @@ class crm_case(object):
self.write(cr, uid, ids, {'state': 'draft', 'active': True})
self._action(cr, uid, cases, 'draft')
return True
def remind_partner(self, cr, uid, ids, context={}, attach=False):
"""
@@ -351,7 +350,7 @@ class crm_case(object):
src = case.email_from
dest = case.section_id.reply_to
body = ""
body = case.email_last or case.description
body = case.email_last or case.description
if not destination:
src, dest = dest, src
if body and case.user_id.signature:
@@ -382,7 +381,7 @@ class crm_case(object):
# raise osv.except_osv(_('Email!'),("Email Successfully Sent"))
#else:
# raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully"))
return True
return True
def _check(self, cr, uid, ids=False, context={}):
"""
@@ -429,12 +428,12 @@ class crm_case_section(osv.osv):
_order = "name"
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'code': fields.char('Code', size=8),
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'code': fields.char('Code', size=8),
'active': fields.boolean('Active', help="If the active field is set to \
true, it will allow you to hide the sales team without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'user_id': fields.many2one('res.users', 'Responsible User'),
true, it will allow you to hide the sales team without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'user_id': fields.many2one('res.users', 'Responsible User'),
'member_ids':fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'),
'reply_to': fields.char('Reply-To', size=64, help="The email address put \
in the 'Reply-To' of all emails sent by Open ERP about cases in this sales team"),
@@ -446,8 +445,8 @@ class crm_case_section(osv.osv):
}
_defaults = {
'active': lambda *a: 1,
'allow_unlink': lambda *a: 1,
'active': lambda *a: 1,
'allow_unlink': lambda *a: 1,
}
_sql_constraints = [
@@ -464,7 +463,7 @@ class crm_case_section(osv.osv):
@param ids: List of Sales team ids
"""
level = 100
while len(ids):
cr.execute('select distinct parent_id from crm_case_section where id =ANY(%s)', (ids,))
ids = filter(None, map(lambda x: x[0], cr.fetchall()))
@@ -510,9 +509,9 @@ class crm_case_categ(osv.osv):
_description = "Category of case"
_columns = {
'name': fields.char('Case Category Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
'name': fields.char('Case Category Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
def _find_object_id(self, cr, uid, context=None):
@@ -542,9 +541,9 @@ class crm_case_resource_type(osv.osv):
_rec_name = "name"
_columns = {
'name': fields.char('Case Resource Type', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
'name': fields.char('Case Resource Type', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
def _find_object_id(self, cr, uid, context=None):
"""Finds id for case object
@@ -573,14 +572,14 @@ class crm_case_stage(osv.osv):
_order = "sequence"
_columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'sequence': fields.integer('Sequence', help="Gives the sequence order \
when displaying a list of case stages."),
'object_id': fields.many2one('ir.model', 'Object Name'),
'probability': fields.float('Probability (%)', required=True),
when displaying a list of case stages."),
'object_id': fields.many2one('ir.model', 'Object Name'),
'probability': fields.float('Probability (%)', required=True),
'on_change': fields.boolean('Change Probability Automatically', \
help="Change Probability on next and previous stages."),
help="Change Probability on next and previous stages."),
'requirements': fields.text('Requirements')
}
def _find_object_id(self, cr, uid, context=None):
@@ -595,8 +594,8 @@ class crm_case_stage(osv.osv):
return ids and ids[0]
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
'object_id' : _find_object_id
}
@@ -620,7 +619,7 @@ class users(osv.osv):
_inherit = 'res.users'
_description = "Users"
_columns = {
'context_section_id': fields.many2one('crm.case.section', 'Sales Team'),
'context_section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
users()
@@ -628,7 +627,7 @@ users()
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
res_partner()
+2 -1
View File
@@ -48,7 +48,7 @@
<field name="date_deadline"/>
<button
name="convert_opportunity"
string="Convert"
string="Convert to Opportunity"
help="Convert to Opportunity"
icon="gtk-index"
type="object"/>
@@ -66,6 +66,7 @@
states="open,pending" type="object"
icon="gtk-go-forward" />
</group>
<field name="type" readonly="1"/>
</group>
<notebook colspan="4">
<page string="Lead">
+3 -3
View File
@@ -26,10 +26,10 @@
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form,graph</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_current':1, 'default_type': 'opportunity'}</field>
<field name="domain">['|',('type','=','opportunity'),('state','=','draft')]</field>
<field name="context">{'search_default_user_id':uid,'search_default_current':1}</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="context">{"search_default_user_id":uid}</field>
<field name="context">{'search_default_current':1, 'default_type': 'opportunity'}</field>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
</record>
+1
View File
@@ -82,6 +82,7 @@
<newline/>
<field name="date_action"/>
<field name="priority" string="Priority"/>
<field name="type" readonly="1"/>
</group>
<notebook colspan="4">
<page string="Opportunity">
+158 -153
View File
File diff suppressed because it is too large Load Diff
+10 -22
View File
@@ -102,9 +102,15 @@ class email_template(osv.osv):
}
_columns = {
'name' : fields.char('Name of Template', size=100, required=True),
'name' : fields.char('Name', size=100, required=True),
'object_name':fields.many2one('ir.model', 'Model'),
'model_int_name':fields.char('Model Internal Name', size=200,),
'enforce_from_account':fields.many2one(
'email_template.account',
string="Enforce From Account",
help="Emails will be sent only from this account."),
'from_email' : fields.related('enforce_from_account', 'email_id',
type='char', string='From',),
'def_to':fields.char(
'Recepient (To)',
size=250,
@@ -141,7 +147,7 @@ class email_template(osv.osv):
help="The text version of the mail",
translate=True),
'use_sign':fields.boolean(
'Use Signature',
'Signature',
help="the signature from the User details"
"will be appened to the mail"),
'file_name':fields.char(
@@ -168,11 +174,6 @@ class email_template(osv.osv):
string="Allowed User Groups",
help="Only users from these groups will be"
" allowed to send mails from this Template"),
'enforce_from_account':fields.many2one(
'email_template.account',
string="Enforce From Account",
help="Emails will be sent only from this account.",
domain="[('company','=','yes')]"),
'model_object_field':fields.many2one(
'ir.model.fields',
string="Field",
@@ -218,6 +219,7 @@ class email_template(osv.osv):
}
_defaults = {
'template_language' : lambda *a:'mako',
}
_sql_constraints = [
@@ -623,19 +625,6 @@ class email_template_preview(osv.osv_memory):
_name = "email_template.preview"
_description = "Email Template Preview"
def _get_model_recs(self, cr, uid, context=None):
if context is None:
context = {}
#Fills up the selection box which allows records from the selected object to be displayed
self.context = context
if 'active_id' in context.keys():
# context['active_id'] = 5
ref_obj_id = self.pool.get('email.template').read(cr, uid, context['active_id'], ['object_name'], context)
ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id[0], ['model'], context)['model']
ref_obj_ids = self.pool.get(ref_obj_name).search(cr, uid, [], context=context)
ref_obj_recs = self.pool.get(ref_obj_name).name_get(cr, uid, ref_obj_ids, context)
return ref_obj_recs
def _default_model(self, cursor, user, context=None):
"""
Returns the default value for model field
@@ -655,7 +644,6 @@ class email_template_preview(osv.osv_memory):
'email.template',
'Template', readonly=True),
'rel_model':fields.many2one('ir.model', 'Model', readonly=True),
'rel_model_ref':fields.selection(_get_model_recs, 'Referred Document'),
'to':fields.char('To', size=250, readonly=True),
'cc':fields.char('CC', size=250, readonly=True),
'bcc':fields.char('BCC', size=250, readonly=True),
@@ -668,7 +656,7 @@ class email_template_preview(osv.osv_memory):
'ref_template': lambda self, cr, uid, ctx:ctx['active_id'],
'rel_model': _default_model
}
# Need to check
def on_change_ref(self, cr, uid, ids, rel_model_ref, context=None):
if context is None:
context = {}
@@ -30,7 +30,7 @@ class email_template_account(osv.osv):
'text/html'
]
_columns = {
'name': fields.char('Email Account Desc',
'name': fields.char('Description',
size=64, required=True,
readonly=True, select=True,
states={'draft':[('readonly', False)]}),
@@ -56,22 +56,16 @@ class email_template_account(osv.osv):
size=120, invisible=True,
required=False, readonly=True,
states={'draft':[('readonly', False)]}),
'smtptls':fields.boolean('Use TLS',
'smtptls':fields.boolean('TLS',
states={'draft':[('readonly', False)]}, readonly=True),
'smtpssl':fields.boolean('Use SSL/TLS (only in python 2.6)',
'smtpssl':fields.boolean('SSL/TLS (only in python 2.6)',
states={'draft':[('readonly', False)]}, readonly=True),
'send_pref':fields.selection([
('html', 'HTML otherwise Text'),
('text', 'Text otherwise HTML'),
('both', 'Both HTML & Text')
], 'Mail Format', required=True),
'allowed_groups':fields.many2many(
'res.groups',
'account_group_rel', 'templ_id', 'group_id',
string="Allowed User Groups",
help="Only users from these groups will be" \
"allowed to send mails from this ID"),
'company':fields.selection([
('yes', 'Yes'),
('no', 'No')
@@ -89,7 +83,7 @@ class email_template_account(osv.osv):
('suspended', 'Suspended'),
('approved', 'Approved')
],
'Account Status', required=True, readonly=True),
'Status', required=True, readonly=True),
}
_defaults = {
@@ -102,7 +96,6 @@ class email_template_account(osv.osv):
['name'],
context
)['name'],
'smtpssl':lambda * a:True,
'state':lambda * a:'draft',
'user':lambda self, cursor, user, context:user,
'send_pref':lambda * a: 'html',
@@ -36,9 +36,6 @@
<field name="send_pref" colspan="2" />
</group>
</page>
<page string="security" attrs="{'invisible':[('company','!=','yes')]}">
<field name="allowed_groups" attrs="{'required':[('company','=','yes')]}" nolabel="1"/>
</page>
</notebook>
<group colspan="4" col="10">
<field name="state" select="1"/>
@@ -52,7 +52,6 @@ class email_template_mailbox(osv.osv):
for attid in values['attachments_ids']:
attachment = self.pool.get('ir.attachment').browse(cr, uid, attid, context)#,['datas_fname','datas'])
payload[attachment.datas_fname] = attachment.datas
print "233333333333333"
result = account_obj.send_mail(cr, uid,
[values['account_id'][0]],
{'To':values.get('email_to', u'') or u'', 'CC':values.get('email_cc', u'') or u'', 'BCC':values.get('email_bcc', u'') or u''},
@@ -153,30 +152,6 @@ class email_template_mailbox(osv.osv):
'folder': lambda * a: 'outbox',
}
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
if context is None:
context = {}
if context.get('company', False):
users_groups = self.pool.get('res.users').browse(cr, uid, uid, context).groups_id
group_acc_rel = {}
#get all accounts and get a table of {group1:[account1,account2],group2:[account1]}
for each_account_id in self.pool.get('email_template.account').search(cr, uid, [('state', '=', 'approved'), ('company', '=', 'yes')], context=context):
account = self.pool.get('email_template.account').browse(cr, uid, each_account_id, context)
for each_group in account.allowed_groups:
if not account.id in group_acc_rel.get(each_group, []):
groups = group_acc_rel.get(each_group, [])
groups.append(account.id)
group_acc_rel[each_group] = groups
users_company_accounts = []
for each_group in group_acc_rel.keys():
if each_group in users_groups:
for each_account in group_acc_rel[each_group]:
if not each_account in users_company_accounts:
users_company_accounts.append(each_account)
args.append(('account_id', 'in', users_company_accounts))
return super(osv.osv, self).search(cr, uid, args, offset, limit,
order, context=context, count=count)
email_template_mailbox()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -53,8 +53,8 @@
</notebook>
<separator colspan="4" string="" />
<group col="4" colspan="4">
<field name="state" colspan="2" readonly="1" />
<button name="complete_mail" type="object" string="Download Full Mail" colspan="2" states="read,unread" />
<field name="state" readonly="1" />
<button name="complete_mail" type="object" string="Download Full Mail" states="read,unread" />
<button name="send_this_mail" type="object" string="Send Mail" />
</group>
</form>
@@ -62,9 +62,8 @@
</record>
<!--============================================= TREE VIEWS =============================================-->
<!--DRAFTS-->
<record model="ir.ui.view" id="email_template_drafts_tree">
<field name="name">email_template.mailbox.draftstree</field>
<record id="view_email_template_mailbox_tree" model="ir.ui.view">
<field name="name">email_template.mailbox.tree</field>
<field name="model">email_template.mailbox</field>
<field name="type">tree</field>
<field name="arch" type="xml">
@@ -77,51 +76,6 @@
</tree>
</field>
</record>
<!--OUTBOX-->
<record model="ir.ui.view" id="email_template_outbox_tree">
<field name="name">email_template.mailbox.outboxtree</field>
<field name="model">email_template.mailbox</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Outbox">
<field name="user" />
<field name="email_from" select="1" />
<field name="subject" select="1" />
<field name="attachments_ids" select="2" />
<field name="date_mail" select="2" />
</tree>
</field>
</record>
<!--SENT-->
<record model="ir.ui.view" id="email_template_sentbox_tree">
<field name="name">email_template.mailbox.sentboxtree</field>
<field name="model">email_template.mailbox</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Sent">
<field name="user" />
<field name="email_from" select="1" />
<field name="subject" select="1" />
<field name="attachments_ids" select="2" />
<field name="date_mail" select="2" />
</tree>
</field>
</record>
<!--TRASH-->
<record model="ir.ui.view" id="email_template_trashbox_tree">
<field name="name">email_template.mailbox.trashboxtree</field>
<field name="model">email_template.mailbox</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Trash">
<field name="user" />
<field name="email_from" select="1" />
<field name="subject" select="1" />
<field name="attachments_ids" select="2" />
<field name="date_mail" select="2" />
</tree>
</field>
</record>
<record id="view_email_template_mailbox_search" model="ir.ui.view">
<field name="name">email_template.mailbox.search</field>
@@ -150,7 +104,7 @@
<field name="res_model">email_template.mailbox</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="email_template_outbox_tree" />
<field name="view_id" ref="view_email_template_mailbox_tree" />
<field name="context">{'group_by': [], 'search_default_draft': 1, 'search_default_outbox': 1}</field>
<field name="search_view_id" ref="view_email_template_mailbox_search"/>
</record>
@@ -62,7 +62,9 @@
<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">
<field name="from_email"/>
<field name="def_to" colspan="4" required="1" />
<field name="def_cc" colspan="4" />
<field name="def_bcc" colspan="4" />
@@ -109,15 +111,7 @@
type="action" colspan="4" target="new" />
</group>
</page>
<page string="Security">
<separator colspan="4" string="Allowed User Groups" />
<field name="allowed_groups" string="Allowed User Groups"
nolabel="1" />
</page>
<page string="Advanced">
<separator string="Automatic Email" colspan="4" />
<field name="enforce_from_account" attrs="{'required':[('auto_email','=',True)]}" />
<newline/>
<field name="ref_ir_act_window" />
<field name="ref_ir_value" />
<separator string="Attachments (Report to attach)" colspan="4"/>
+1
View File
@@ -31,6 +31,7 @@
<group colspan="8">
<field name="marketing_campaign" />
<field name="crm_profiling" />
<field name="marketing_campaign_mailchimp" />
</group>
</data>
</field>
+2
View File
@@ -28,6 +28,8 @@ class marketing_installer(osv.osv_memory):
# Generic modules
'marketing_campaign':fields.boolean('Marketing Campaigns',
help="Helps you to manage marketing campaigns and automate actions and communication steps."),
'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration',
help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."),
'crm_profiling':fields.boolean('Profiling Tools',
help="Helps you to perform segmentation within partners and design questionaires.")
}
+158 -113
View File
@@ -25,7 +25,7 @@ from dateutil.relativedelta import relativedelta
from osv import fields, osv
import netsvc
import tools
import tools
_intervalTypes = {
'hours': lambda interval: relativedelta(hours=interval),
@@ -37,12 +37,12 @@ _intervalTypes = {
class marketing_campaign(osv.osv): #{{{
_name = "marketing.campaign"
_description = "Marketing Campaign"
_columns = {
'name': fields.char('Name', size=64, required=True),
'object_id': fields.many2one('ir.model', 'Objects', required=True,
'object_id': fields.many2one('ir.model', 'Object', required=True,
help="Choose the Object on which you want \
this campaign to be run"),
this campaign to be run"),
'mode':fields.selection([('test', 'Test'),
('test_realtime', 'Realtime'),
('manual', 'Manual'),
@@ -52,17 +52,15 @@ class marketing_campaign(osv.osv): #{{{
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled'),],
'State',),
'activity_ids': fields.one2many('marketing.campaign.activity',
'State',),
'activity_ids': fields.one2many('marketing.campaign.activity',
'campaign_id', 'Activities'),
'fixed_cost': fields.float('Fixed Cost', help="The fixed cost is cost\
you required for the campaign"),
you required for the campaign"),
}
_defaults = {
'state': lambda *a: 'draft',
'mode': lambda *a: 'test',
'mode': lambda *a: 'test',
}
def state_running_set(self, cr, uid, ids, *args):
@@ -79,16 +77,16 @@ class marketing_campaign(osv.osv): #{{{
('state', '=', 'draft')])
self.write(cr, uid, ids, {'state': 'running'})
return True
def state_done_set(self, cr, uid, ids, *args):
segment_ids = self.pool.get('marketing.campaign.segment').search(cr, uid,
[('campaign_id', 'in', ids),
('state', '=', 'running')])
if segment_ids :
raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
self.write(cr, uid, ids, {'state': 'done'})
return True
def state_cancel_set(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'cancelled'})
return True
@@ -100,7 +98,7 @@ class marketing_campaign_segment(osv.osv): #{{{
_columns = {
'name': fields.char('Name', size=64,required=True),
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
required=True),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
@@ -114,32 +112,32 @@ class marketing_campaign_segment(osv.osv): #{{{
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled')],
'State',),
'State',),
'date_run': fields.datetime('Running'),
'date_done': fields.datetime('Done'),
}
_defaults = {
'state': lambda *a: 'draft',
'sync_mode': lambda *a: 'create_date',
}
def state_running_set(self, cr, uid, ids, *args):
segment = self.browse(cr, uid, ids[0])
curr_date = time.strftime('%Y-%m-%d %H:%M:%S')
vals = {'state': 'running'}
if not segment.date_run:
vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
if not segment.sync_last_date:
vals['sync_last_date']=curr_date
if not segment.date_done:
vals['date_done']= (datetime.now() + _intervalTypes['years'](1) \
).strftime('%Y-%m-%d %H:%M:%S')
vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
# if not segment.sync_last_date:
# vals['sync_last_date']=curr_date
# if not segment.date_done:
# vals['date_done']= (datetime.now() + _intervalTypes['years'](1) \
# ).strftime('%Y-%m-%d %H:%M:%S')
self.write(cr, uid, ids, vals)
return True
def state_done_set(self, cr, uid, ids, *args):
date_done = self.browse(cr, uid, ids[0]).date_done
date_done = self.browse(cr, uid, ids[0]).date_done
if (date_done > time.strftime('%Y-%m-%d %H:%M:%S')):
raise osv.except_osv("Error", "Segment cannot be closed before end date")
@@ -147,30 +145,40 @@ class marketing_campaign_segment(osv.osv): #{{{
[('state', 'in', ['inprogress', 'todo']),
('segment_id', '=', ids[0])])
if wi_ids :
raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
self.write(cr, uid, ids, {'state': 'done'})
return True
def state_cancel_set(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'cancelled'})
return True
def synchroniz(self, cr, uid, ids, *args):
self.process_segment(cr, uid, {'segment_ids' : ids})
return True
def process_segment(self, cr, uid, context={}):
segment_ids = self.search(cr, uid, [('state', '=', 'running')])
last_action_date = ''
if 'segment_ids' in context:
segment_ids = context['segment_ids']
last_action_date = (datetime.now() + _intervalTypes['days'](-1) \
).strftime('%Y-%m-%d %H:%M:%S')
else :
segment_ids = self.search(cr, uid, [('state', '=', 'running')])
action_date = time.strftime('%Y-%m-%d %H:%M:%S')
last_action_date = (datetime.now() + _intervalTypes['days'](-1) \
).strftime('%Y-%m-%d %H:%M:%S')
for segment in self.browse(cr, uid, segment_ids):
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
uid, [('start', '=', True),
('campaign_id', '=', segment.campaign_id.id)])
if (segment.sync_last_date and \
segment.sync_last_date <= action_date )\
or not segment.sync_last_date :
model_obj = self.pool.get(segment.object_id.model)
object_ids = model_obj.search(cr, uid, [
(segment.sync_mode, '<=', action_date),
(segment.sync_mode, '>=', last_action_date)])
criteria = [(segment.sync_mode, '<=', action_date)]
if last_action_date :
criteria.append((segment.sync_mode, '>=', last_action_date))
object_ids = model_obj.search(cr, uid, criteria)
for o_ids in model_obj.read(cr, uid, object_ids) :
partner_id = 'partner_id' in o_ids and o_ids['partner_id'] \
or False
@@ -192,26 +200,30 @@ marketing_campaign_segment()#}}}
class marketing_campaign_activity(osv.osv): #{{{
_name = "marketing.campaign.activity"
_description = "Campaign Activity"
_actions_type = [('email', 'E-mail'), ('paper', 'Paper'), ('action', 'Action'),
('subcampaign', 'Sub-Campaign')]
_columns = {
'name': fields.char('Name', size=128, required=True),
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
required = True, ondelete='cascade'),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
string='Object'),
'start': fields.boolean('Start',help= "Its necessary to start activity \
before running campaign"),
'condition': fields.char('Condition', size=256, required=True,
help="Condition that is to be tested before \
action is executed"),
before running campaign"),
'condition': fields.char('Condition', size=256, required=True,
help="It is simple python condition that is to \
be tested before action is executed. Eg : revenue > 10"),
'type': fields.selection([('email', 'E-mail'),
('paper', 'Paper'),
('action', 'Action'),
('subcampaign', 'Sub-Campaign')],
'Type', required=True),
'Type', required=True,
help="Describe type of action to be performed on the Activity.\
Eg : Send email,Send paper.."),
'email_template_id': fields.many2one('email.template','Email Template'),
'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
'report_directory_id': fields.many2one('document.directory','Directory',
help="Folder is used to store the generated reports"),
'server_action_id': fields.many2one('ir.actions.server', string='Action',
@@ -222,7 +234,7 @@ class marketing_campaign_activity(osv.osv): #{{{
'Next Activities'),
'from_ids': fields.one2many('marketing.campaign.transition',
'activity_to_id',
'Previous Activities'),
'Previous Activities'),
'subcampaign_id': fields.many2one('marketing.campaign', 'Sub-Campaign'),
'subcampaign_segment_id': fields.many2one('marketing.campaign.segment',
'Sub Campaign Segment'),
@@ -235,8 +247,15 @@ class marketing_campaign_activity(osv.osv): #{{{
'condition': lambda *a: 'True',
'object_id' : lambda obj, cr, uid, context : context.get('object_id',False),
}
def __init__(self, *args):
self._actions = {'paper' : self.process_wi_report,
'email' : self.process_wi_email,
'server_action' : self.process_wi_action,
}
return super(marketing_campaign_activity, self).__init__(*args)
def search(self, cr, uid, args, offset=0, limit=None, order=None,
def search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False):
if context == None:
context = {}
@@ -247,58 +266,65 @@ class marketing_campaign_activity(osv.osv): #{{{
for activity in segment_obj.campaign_id.activity_ids:
act_ids.append(activity.id)
return act_ids
return super(marketing_campaign_activity, self).search(cr, uid, args,
return super(marketing_campaign_activity, self).search(cr, uid, args,
offset, limit, order, context, count)
def process(self, cr, uid, act_id, wi_id, context={}):
activity = self.browse(cr, uid, act_id)
workitem_obj = self.pool.get('marketing.campaign.workitem')
workitem = workitem_obj.browse(cr, uid, wi_id)
if activity.type == 'paper' :
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {})
attach_vals = {
'name': '%s_%s_%s'%(activity.report_id.report_name,
activity.name,workitem.partner_id.name),
'datas_fname': '%s.%s'%(activity.report_id.report_name,
activity.report_id.report_type),
'parent_id': activity.report_directory_id.id,
'datas': base64.encodestring(report_data),
'file_type': format
}
self.pool.get('ir.attachment').create(cr, uid, attach_vals)
elif activity.type == 'email' :
context = {}
template = activity.email_template_id
accounts = template.enforce_from_account
if not template.enforce_from_account:
return {'error_msg' : "There is no account defined for the email"}
if not workitem.partner_id.email:
return {'error_msg' : "There is no email defined for the partner"}
vals = {
'email_from': tools.ustr(accounts.name) + "<" + tools.ustr(accounts.email_id) + ">",
'email_to': workitem.partner_id.email,
'subject': template.def_subject,
'body_text': template.def_body_text,
'body_html': template.def_body_html,
'account_id':accounts.id,
'state':'na',
'mail_type':'multipart/alternative' #Options:'multipart/mixed','multipart/alternative','text/plain','text/html'
}
def process_wi_report(self, cr, uid, activity, workitem):
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {})
attach_vals = {
'name': '%s_%s_%s'%(activity.report_id.report_name,
activity.name,workitem.partner_id.name),
'datas_fname': '%s.%s'%(activity.report_id.report_name,
activity.report_id.report_type),
'parent_id': activity.report_directory_id.id,
'datas': base64.encodestring(report_data),
'file_type': format
}
self.pool.get('ir.attachment').create(cr, uid, attach_vals)
return True
def process_wi_email(self, cr, uid, activity, workitem):
template = activity.email_template_id
accounts = template.enforce_from_account
if not template.enforce_from_account:
return {'error_msg' : "There is no account defined for the email"}
if not workitem.partner_id.email:
return {'error_msg' : "There is no email defined for the partner"}
vals = {
'email_from': tools.ustr(accounts.name) + "<" + tools.ustr(accounts.email_id) + ">",
'email_to': workitem.partner_id.email,
'subject': template.def_subject,
'body_text': template.def_body_text,
'body_html': template.def_body_html,
'account_id':accounts.id,
'state':'na',
'mail_type':'multipart/alternative' #Options:'multipart/mixed','multipart/alternative','text/plain','text/html'
}
# if accounts.use_sign:
# signature = self.pool.get('res.users').read(cr, uid, uid, ['signature'], context)['signature']
# if signature:
# vals['pem_body_text'] = tools.ustr(vals['pem_body_text'] or '') + signature
# vals['pem_body_html'] = tools.ustr(vals['pem_body_html'] or '') + signature
#Create partly the mail and later update attachments
mail_id = self.pool.get('email_template.mailbox').create(cr, uid, vals, context)
elif activity.type == 'action' :
server_obj = self.pool.get('ir.actions.server')
server_obj.run(cr, uid, [activity.server_action_id.id], context)
#???
#Create partly the mail and later update attachments
mail_id = self.pool.get('email_template.mailbox').create(cr, uid, vals, context)
return True
def process_wi_action(self, cr, uid, activity, workitem):
context = {}
server_obj = self.pool.get('ir.actions.server')
server_obj.run(cr, uid, [activity.server_action_id.id], context)
return True
def process(self, cr, uid, act_id, wi_id, context={}):
activity = self.browse(cr, uid, act_id)
workitem_obj = self.pool.get('marketing.campaign.workitem')
workitem = workitem_obj.browse(cr, uid, wi_id)
self._actions[activity.type](cr, uid, activity, workitem)
return True
marketing_campaign_activity()#}}}
class marketing_campaign_transition(osv.osv): #{{{
@@ -309,10 +335,10 @@ class marketing_campaign_transition(osv.osv): #{{{
_columns = {
'activity_from_id': fields.many2one('marketing.campaign.activity',
'Source Activity'),
'activity_to_id': fields.many2one('marketing.campaign.activity',
'activity_to_id': fields.many2one('marketing.campaign.activity',
'Destination Activity'),
'interval_nbr': fields.integer('Interval No.'),
'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
('months', 'Months'),
('years','Years')],'Interval Type')
}
@@ -323,32 +349,46 @@ class marketing_campaign_transition(osv.osv): #{{{
if context.has_key('type_id'):
value[context['type_id']] = context['activity_id']
return value
marketing_campaign_transition() #}}}
class marketing_campaign_workitem(osv.osv): #{{{
_name = "marketing.campaign.workitem"
_description = "Campaign Workitem"
def _res_name_get(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for obj in self.browse(cr, uid, ids, context=context):
if obj.res_id:
try:
res[obj.id] = self.pool.get(obj.object_id.model).name_get(cr, uid, [obj.res_id], context=context)[0][1]
except:
res[obj.id] = '/'
else:
res[obj.id] = '/'
return res
_columns = {
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment',
required=True),
required=True),
'activity_id': fields.many2one('marketing.campaign.activity','Activity',
required=True),
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
type='many2one', relation='ir.model',
string='Object'),
'res_id': fields.integer('Results'),
required=True),
'campaign_id': fields.related('segment_id', 'campaign_id',
type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
type='many2one', relation='ir.model', string='Object'),
'res_id': fields.integer('Resource ID'),
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64),
'date': fields.datetime('Execution Date'),
'partner_id': fields.many2one('res.partner', 'Partner',required=True),
'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
('exception', 'Exception'), ('done', 'Done'),
('cancelled', 'Cancelled')], 'State'),
'error_msg' : fields.text('Error Message')
}
}
_defaults = {
'state': lambda *a: 'draft',
'state': lambda *a: 'todo',
}
def process_chain(self, cr, uid, workitem_id, context={}):
@@ -369,11 +409,17 @@ class marketing_campaign_workitem(osv.osv): #{{{
'state': 'todo',
}
self.create(cr, uid, workitem_vals)
def button_cancel(self, cr, uid, workitem_ids, context={}):
for wi in self.browse(cr, uid, workitem_ids):
if wi.state in ('todo','exception'):
self.write(cr, uid, [wi.id], {'state':'cancelled'}, context=context)
return True
def process(self, cr, uid, workitem_ids, context={}):
for wi in self.browse(cr, uid, workitem_ids):
if wi.state == 'todo':# we searched the wi which are in todo state
#then y v keep this filter again
if wi.state == 'todo':# we searched the wi which are in todo state
#then y v keep this filter again
eval_context = {
'pool': self.pool,
'cr': cr,
@@ -390,45 +436,44 @@ class marketing_campaign_workitem(osv.osv): #{{{
if res :
self.write(cr, uid, wi.id, {'state': 'done'})
self.process_chain(cr, uid, wi.id, context)
else :
else :
self.write(cr, uid, wi.id, {'state': 'exception',
'error_msg': res['error_msg']})
except Exception,e:
self.write(cr, uid, wi.id, {'state': 'exception'})
else :
self.write(cr, uid, wi.id, {'state': 'cancelled'})
return True
def process_all(self, cr, uid, context={}):
workitem_ids = self.search(cr, uid, [('state', '=', 'todo'),
('date','<=', time.strftime('%Y-%m-%d %H:%M:%S'))])
if workitem_ids:
self.process(cr, uid, workitem_ids, context)
marketing_campaign_workitem() #}}}
marketing_campaign_workitem() #}}}
class email_template(osv.osv):
_inherit = "email.template"
_defaults = {
'object_name': lambda obj, cr, uid, context: context.get('object_id',False),
}
email_template()
email_template()
class report_xml(osv.osv):
_inherit = 'ir.actions.report.xml'
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
if not context:
context = {}
if context and 'object_id' in context and context['object_id']:
model = self.pool.get('ir.model').browse(cr, uid,
model = self.pool.get('ir.model').browse(cr, uid,
context['object_id']).model
args.append(('model', '=', model))
return super(report_xml, self).search(cr, uid, args, offset, limit, order, context, count)
report_xml()
report_xml()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -14,75 +14,67 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Campaign">
<group colspan="4">
<group colspan="4" col="6">
<field name="name" select="1"/>
<field name="object_id" select="1"/>
<field name="mode"/>
<field name="fixed_cost"/>
</group>
<field name="activity_ids" nolabel = "1" colspan="4" default_get="{'object_id':object_id}">
<form string="Activities">
<field name="name" select="1" />
<field name="object_id" readonly="True"/>
<field name="variable_cost" select="1"/>
<field name="start"/>
<field name="condition" colspan="4"/>
<form string="Activities">
<group colspan="4" col="6">
<separator string="Activity Definition" colspan="4"/>
<separator string="Cost Control" colspan="2"/>
<field name="name" select="1" />
<field name="start"/>
<field name="variable_cost" select="1"/>
</group>
<group colspan="2" col="2">
<separator string="Condition" colspan="2"/>
<field name="condition"/>
</group>
<group colspan="2" col="2">
<separator string="Action" colspan="2"/>
<field name="type" colspan="4"/>
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
</group>
</group>
<newline/>
<field name="type" colspan="4"/>
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
</group>
<field name="to_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
<form string="Out Transitions" >
<field name="activity_from_id" readonly="True"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</form>
<tree string="Out Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
<field name="from_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
<form string="In Transitions" >
<field name="activity_from_id"/>
<field name="activity_to_id" readonly="True"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</form>
<tree string="In Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
<group colspan="4" col="4">
<separator string="Transitions" colspan="4"/>
<field name="to_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
<tree string="Outgoing Transitions" editable="bottom">
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
<field name="from_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
<tree string="Incoming Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
</group>
</form>
<tree string="Activities">
<field name="name" select="1"/>
<field name="object_id"/>
<field name="name"/>
<field name="start"/>
<field name="condition"/>
<field name="variable_cost" select="1"/>
<field name="type"/>
<field name="report_id"/>
<field name="to_ids"/>
<field name="subcampaign_id"/>
<field name="subcampaign_segment_id"/>
</tree>
</field>
<separator string="Status" colspan="4" />
@@ -105,7 +97,6 @@
<field name="name" select="1"/>
<field name="object_id" select="1"/>
<field name="mode"/>
<field name="fixed_cost"/>
<field name="state"/>
</tree>
</field>
@@ -122,13 +113,13 @@
<field name="type"/>
<field name="start" invisible="1"/>
<field name="condition"/>
</node>
<arrow object="marketing.campaign.transition" source="activity_from_id" destination="activity_to_id" label="['interval_type']">
</node>
<arrow object="marketing.campaign.transition" source="activity_from_id" destination="activity_to_id" label="['interval_type']">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</arrow>
<field name="interval_type"/>
</arrow>
</diagram>
</field>
</record>
@@ -183,21 +174,24 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Segments">
<group colspan="4">
<field name="name" select="1" colspan="4"/>
<newline/>
<group colspan="4" col="6">
<field name="name"/>
<field name="campaign_id" select="1"/>
<field name="object_id" select="1" readonly="True"/>
<newline/>
<field name="ir_filter_id" select="1"/>
<newline/>
<field name="object_id" invisible="1" readonly="True"/>
</group>
<group colspan="2" col="2">
<separator string="Synchronization" colspan="2"/>
<field name="sync_last_date"/>
<field name="sync_mode" required="True"/>
<button string="Synchroniz" states="draft,running" name="synchroniz" icon="gtk-apply" type="object"/>
</group>
<group colspan="2" col="2">
<separator string="Dates" colspan="2"/>
<field name="date_run" attrs="{'readonly':[('date_run','!=',False),('state','=','running')]}"/>
<field name="date_done"/>
<separator string="Synchronization" colspan="4" />
<field name="sync_last_date"/>
<field name="sync_mode" required="True"/>
</group>
<separator string="Status" colspan="4" />
<separator string="Status" colspan="4"/>
<group col="10" colspan="4">
<field name="state" readonly="1" select="2" nolabel="1"/>
<button name="state_running_set" string="Run" states="draft" icon="gtk-apply"/>
@@ -214,13 +208,10 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Segments">
<field name="name" select="1"/>
<field name="campaign_id" select="1"/>
<field name="object_id" select="1" />
<field name="name"/>
<field name="campaign_id"/>
<field name="date_run"/>
<field name="date_done"/>
<field name="sync_last_date" string="Sync Date"/>
<field name="sync_mode" string="Sync Mode"/>
<field name="sync_last_date"/>
<field name="state" />
</tree>
</field>
@@ -232,10 +223,10 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Segments">
<filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]"/>
<filter icon="terp-check" string="Running" domain="[('state','=','running')]"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]"/>
<filter icon="terp-check" string="Running" name="running" domain="[('state','=','running')]"/>
<separator orientation="vertical"/>
<filter icon="terp-go-month" string="Create Date" name="create_date" domain="[('sync_mode','=','create_date')]"/>
<filter icon="terp-go-month" string="Create Date" domain="[('sync_mode','=','create_date')]"/>
<filter icon="terp-go-month" string="Write Date" domain="[('sync_mode','=','write_date')]"/>
<separator orientation="vertical"/>
<field name="name" select="1"/>
@@ -251,7 +242,7 @@
</search>
</field>
</record>
+
<record model="ir.actions.act_window" id="action_marketing_campaign_segment_form">
<field name="name">Segments</field>
<field name="type">ir.actions.act_window</field>
@@ -259,8 +250,8 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_marketing_campaign_segment_tree"/>
<field name="search_view_id" ref="view_marketing_campaign_segment_search"/>
<field name="context">{'group_by': [], 'search_default_draft': 1, 'search_default_create_date': 1}</field>
<field name="search_view_id" ref="view_marketing_campaign_segment_search"/>
<field name="context">{'group_by': [], 'search_default_running': 1}</field>
</record>
<menuitem id="menu_marketing_campaign_segment_form" parent="menu_marketing_campaign" action="action_marketing_campaign_segment_form" sequence="20" />
@@ -277,54 +268,55 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Activities">
<field name="name" select="1" />
<field name="start"/>
<field name="campaign_id" select="1"/>
<field name="object_id" readonly="True"/>
<group colspan="4" col="6">
<separator string="Activity Definition" colspan="4"/>
<separator string="Cost Control" colspan="2"/>
<field name="name" select="1" />
<field name="start"/>
<field name="variable_cost" select="1"/>
<field name="object_id" invisible="1"/>
</group>
<group colspan="2" col="2">
<separator string="Condition" colspan="2"/>
<field name="condition"/>
</group>
<group colspan="2" col="2">
<separator string="Action"/>
<field name="type" colspan="4"/>
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
</group>
</group>
<newline/>
<field name="type"/>
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
<group colspan="4" col="4">
<separator string="Transitions" colspan="4"/>
<field name="to_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
<tree string="Outgoing Transitions" editable="bottom">
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
<field name="from_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
<tree string="Incoming Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}" />
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
</group>
<field name="to_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
<form string="Out Transitions" >
<field name="activity_from_id" readonly="True"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</form>
<tree string="Out Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
<field name="from_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
<form string="In Transitions" >
<field name="activity_from_id"/>
<field name="activity_to_id" readonly="True"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</form>
<tree string="In Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
<field name="interval_nbr"/>
<field name="interval_type"/>
</tree>
</field>
</form>
</field>
</record>
@@ -338,13 +330,8 @@
<field name="name" select="1"/>
<field name="campaign_id" select="1"/>
<field name="start"/>
<field name="object_id"/>
<field name="condition"/>
<field name="type"/>
<field name="report_id"/>
<field name="to_ids" />
<field name="subcampaign_id"/>
<field name="subcampaign_segment_id"/>
</tree>
</field>
</record>
@@ -374,11 +361,12 @@
<tree string="Workitems">
<field name="segment_id"/>
<field name="activity_id" />
<field name="object_id"/>
<field name="partner_id" select="1"/>
<field name="res_id" />
<field name="res_name" />
<field name="partner_id"/>
<field name="date"/>
<field name="state"/>
<button string="Process" states="todo" name="process" type="object" icon="gtk-ok"/>
<button string="Cancel" states="todo" name="button_cancel" type="object" icon="gtk-cancel"/>
</tree>
</field>
</record>
@@ -389,14 +377,31 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Workitem">
<field name="segment_id" select="1"/>
<field name="activity_id" context="{'segment_id':segment_id}" select="1"/>
<field name="object_id" readonly="True"/>
<field name="partner_id" select="1"/>
<field name="res_id"/>
<field name="date" select="1"/>
<group colspan="4" col="6">
<group colspan="2" col="2">
<separator string="Campaign Step" colspan="2"/>
<field name="campaign_id" select="1"/>
<field name="segment_id" select="1"/>
<field name="activity_id" context="{'segment_id':segment_id}" select="1"/>
</group><group colspan="2" col="2">
<separator string="Related Resource" colspan="2"/>
<field name="object_id" readonly="True"/>
<field name="res_name"/>
<field name="res_id"/>
<field name="partner_id" select="1"/>
</group><group colspan="2" col="2">
<separator string="Date" colspan="2"/>
<field name="date"/>
<label string="" colspan="1"/>
<button string="Preview" states="todo" name="preview" icon="gtk-apply" type="object"/>
</group>
</group>
<separator string="Status" colspan="4"/>
<field name="state" nolabel="1" colspan="4" readonly="True" select="1"/>
<group colspan="4" col="11">
<field name="state" nolabel="1" readonly="True" select="1"/>
<button string="Process" states="todo" name="process" type="object" icon="gtk-ok"/>
<button string="Cancel" states="todo" name="button_cancel" type="object" icon="gtk-cancel"/>
</group>
</form>
</field>
</record>
@@ -440,5 +445,14 @@
<menuitem id="menu_action_marketing_campaign_workitem" parent="menu_marketing_campaign" action="action_marketing_campaign_workitem" sequence="30" groups="base.group_extended"/>
<act_window name="All Segments"
res_model="marketing.campaign.segment"
src_model="marketing.campaign"
view_type="form"
view_mode="tree,form"
id="act_marketing_campaing_segment_opened"
domain="[('campaign_id','=',active_id)]"
/>
</data>
</openerp>
+6 -5
View File
@@ -358,10 +358,11 @@ class Partner(osv.osv):
def __get_membership_state(self, *args, **kwargs):
return self._membership_state(*args, **kwargs)
_columns = {
'associate_member': fields.many2one('res.partner', 'Associate member'),
'member_lines': fields.one2many('membership.membership_line', 'partner', 'Membership'),
'member': fields.boolean('Member'),
'free_member': fields.boolean('Free member'),
'membership_amount': fields.float(
'Membership amount', digits=(16, 2),
@@ -422,16 +423,16 @@ class Partner(osv.osv):
_constraints = [
(_check_recursion, 'Error ! You can not create recursive associated members.', ['associate_member'])
]
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if context is None:
context = {}
context = {}
default = default.copy()
default['member_lines'] = []
return super(Partner, self).copy(cr, uid, id, default, context)
Partner()
class product_template(osv.osv):
@@ -646,7 +647,7 @@ ReportPartnerMemberYearNew()
class account_invoice_line(osv.osv):
_inherit='account.invoice.line'
def write(self, cr, uid, ids, vals, context=None):
if not context:
context={}
+31 -1
View File
@@ -103,13 +103,14 @@
<field name="arch" type="xml">
<tree string="Members">
<field name="name"/>
<field name="associate_member" attrs="{'invisible':[('membership_state', '!=', 'none')]}"/>
<field name="membership_start"/>
<field name="membership_stop"/>
<field name="membership_state"/>
<field name="associate_member" attrs="{'invisible':[('membership_state', '!=', 'none')]}"/>
</tree>
</field>
</record>
<record id="view_res_partner_member_filter" model="ir.ui.view">
<field name="name">res.partner.select</field>
<field name="model">res.partner</field>
@@ -125,6 +126,24 @@
</field>
</record>
<record id="view_res_partner_member_filter2" model="ir.ui.view">
<field name="name">res.partner.select2</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="view_res_partner_member_filter"/>
<field name="type">search</field>
<field name="arch" type="xml">
<field name="membership_state" position="after">
<group expand="1" string="Group By" colspan="10" col="8">
<separator orientation="vertical"/>
<filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_start'}"/>
<filter string="End Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_stop'}"/>
<filter string="Associate Member" icon="terp-personal" domain="[]" context="{'group_by':'associate_member'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'membership_state'}"/>
</group>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="action_membership_members">
<field name="name">Members</field>
<field name="res_model">res.partner</field>
@@ -157,6 +176,17 @@
/>
-->
<record id="view_res_partner_member_form2" model="ir.ui.view">
<field name="name">res.partner.form2</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="supplier" position="after">
<field name="member"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_partner_tree">
<field name="name">res.partner.tree.form.inherit</field>
+1 -1
View File
@@ -248,7 +248,7 @@ class mrp_bom(osv.osv):
v['name'] = prod.name
return {'value': v}
return {}
def _bom_find(self, cr, uid, product_id, product_uom, properties=[]):
""" Finds BoM for particular product and product uom.
@param product_id: Selected product.
+1 -1
View File
@@ -248,7 +248,7 @@
<field name="name" select="1"/>
<field name="code" select="1" string="Reference" groups="base.group_extended"/>
<newline/>
<field name="product_uom" widget="selection"/>
<field name="product_uom"/>
<field name="product_qty"/>
<field name="routing_id" widget="selection" groups="base.group_extended"/>
<newline/>
+2 -2
View File
@@ -265,10 +265,10 @@
<para style="terp_default_Centre_8">[[ formatLang(o.date_planned, date_time = True) ]]</para>
</td>
<td>
<para style="terp_default_Centre_8">[[ o.sale_ref or ' ' ]]</para>
<para style="terp_default_Centre_8">[[ o.sale_ref or removeParentNode('para')]]</para>
</td>
<td>
<para style="terp_default_Centre_8">[[ o.sale_name or '' ]]</para>
<para style="terp_default_Centre_8">[[ o.sale_name or removeParentNode('para') ]]</para>
</td>
</tr>
</blockTable>
+1 -6
View File
@@ -145,11 +145,6 @@ parameter) will see those record just disappear.
<field name="name">Stock Weight</field>
<field name="digits">2</field>
</record>
<record forcecreate="True" id="property_stock_variation" model="ir.property">
<field name="name">property_stock_variation</field>
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_variation')]"/>
<field eval="'account.account,'+str(ref('account.a_recv'))" model="account.account" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
</data>
</openerp>
+29 -28
View File
@@ -69,7 +69,7 @@ class project_issue(osv.osv, crm.crm_case):
duration = 0
ans = False
hours = 0
if field in ['working_hours_open','day_open']:
if issue.date_open:
date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
@@ -121,38 +121,38 @@ class project_issue(osv.osv, crm.crm_case):
return res
_columns = {
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID'),
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID'),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
'active': fields.boolean('Active', required=False),
'create_date': fields.datetime('Creation Date' , readonly=True),
'write_date': fields.datetime('Update Date' , readonly=True),
'date_deadline': fields.date('Deadline'),
'date_closed': fields.datetime('Closed', readonly=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),
Define Responsible user and Email account for mail gateway.'),
'user_id': fields.many2one('res.users', 'Responsible'),
'partner_id': fields.many2one('res.partner', 'Partner'),
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
domain="[('partner_id','=',partner_id)]"),
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Description'),
domain="[('partner_id','=',partner_id)]"),
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Description'),
'state': fields.selection([
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('pending', 'Pending'),
], 'State', size=16, readonly=True,
], 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'email_cc': fields.text('Watchers Emails', size=252 , help="These people\
will receive a copy of the future" \
" communication between partner and users by email"),
" communication between partner and users by email"),
'date_open': fields.datetime('Opened', readonly=True),
# Project Issue fields
'date_closed': fields.datetime('Closed', readonly=True),
@@ -180,7 +180,7 @@ class project_issue(osv.osv, crm.crm_case):
'working_hours_close': fields.function(_compute_day, string='Working Hours to Close the Issue', \
method=True, multi='working_days_close', type="float", store=True),
}
def _get_project(self, cr, uid, context):
user = self.pool.get('res.users').browse(cr,uid,uid, context=context)
if user.context_project_id:
@@ -189,14 +189,14 @@ class project_issue(osv.osv, crm.crm_case):
_defaults = {
'active': lambda *a: 1,
'user_id': crm.crm_case._get_default_user,
'partner_id': crm.crm_case._get_default_partner,
'partner_address_id': crm.crm_case._get_default_partner_address,
'email_from': crm.crm_case. _get_default_email,
'user_id': crm.crm_case._get_default_user,
'partner_id': crm.crm_case._get_default_partner,
'partner_address_id': crm.crm_case._get_default_partner_address,
'email_from': crm.crm_case. _get_default_email,
'state': lambda *a: 'draft',
'section_id': crm.crm_case. _get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'section_id': crm.crm_case. _get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'project_id':_get_project,
}
@@ -277,7 +277,7 @@ class project_issue(osv.osv, crm.crm_case):
if not stage.on_change:
return {'value':{}}
return {'value':{}}
def case_escalate(self, cr, uid, ids, *args):
"""Escalates case to top level
@param self: The object pointer
@@ -286,16 +286,17 @@ class project_issue(osv.osv, crm.crm_case):
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = super(project_issue, self).case_escalate(cr, uid, ids, args)
cases = self.browse(cr, uid, ids)
for case in cases:
data = {}
if case.project_id.project_escalation_id:
data['project_id'] = case.project_id.project_escalation_id.id
if case.project_id.project_escalation_id.user_id:
data['user_id'] = case.project_id.project_escalation_id.user_id.id
else:
raise osv.except_osv(_('Warning !'), _('You cannot escalate this case.\nThe relevant Project has not configured the Escalation Project!'))
raise osv.except_osv(_('Warning !'), _('You cannot escalate this issue.\nThe relevant Project has not configured the Escalation Project!'))
self.write(cr, uid, [case.id], data)
return res
return True
project_issue()
+10 -1
View File
@@ -14,7 +14,7 @@
<field name="view_mode">tree,calendar</field>
<field name="view_id" ref="project_issue_tree_view"/>
<field name="domain" eval="[('categ_id','=',ref('bug_categ'))]"/>
<field name="context">{"search_default_user_id": uid, "search_default_my_bugs":1,"search_default_current_bugs":1,"search_default_project_id":project_id}</field>
<field name="context">{"search_default_user_id": uid,"search_default_current":1,"search_default_project_id":project_id}</field>
<field name="search_view_id" ref="view_project_issue_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view0">
@@ -36,6 +36,15 @@
<field name="act_window_id" ref="project_issue_categ_act0"/>
</record>
<act_window
domain="[('project_id', '=', active_id)]"
id="act_project_project_2_project_issue_all"
name="Issues"
res_model="project.issue"
src_model="project.project"
view_mode="tree,form,calendar,graph"
view_type="form"/>
<!--<menuitem id="menu_aftertask" name="Bug" parent="project.menu_main" visible="False"/>-->
<menuitem name="Issues" id="menu_project_issue_track" parent="project.menu_project_management" action="project_issue_categ_act0"/>
</data>
+47 -51
View File
@@ -32,6 +32,8 @@
<form string="Issue Tracker Form">
<group colspan="4" col="6">
<field name="name"/>
<field name="project_id" required="True"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
<field name="user_id"/>
<field name="assigned_to" />
<group colspan="2" col="4">
@@ -39,8 +41,6 @@
<button icon="gtk-go-back" string="" name="stage_previous" type="object"/>
<button icon="gtk-go-forward" string="" name="stage_next" type="object"/>
</group>
<field name="project_id" required="True"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
</group>
<notebook colspan="4">
<page string="General">
@@ -73,40 +73,6 @@
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert"/>
</group>
</page>
<page string="History" groups="base.group_extended">
<group col="2" colspan="2">
<separator colspan="2" string="Date"/>
<field name="create_date"/>
<field name="write_date" />
<field name="date_closed"/>
<field name="date_open"/>
</group>
<group colspan="2" col="2">
<separator string="Statistics" colspan="2" col="2"/>
<field name="day_open"/>
<field name="day_close"/>
<field name="working_hours_open" widget="float_time"/>
<field name="working_hours_close" widget="float_time"/>
</group>
<group colspan="2" col="2">
<separator string="References" colspan="2"/>
<field name="id"/>
<field name="active"/>
</group>
<field name="log_ids" nolabel="1" colspan="4">
<tree string="Logs">
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</tree>
<form string="Logs">
<separator string="Action Information" colspan="4"/>
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</form>
</field>
</page>
<page string="Emails" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="CC"/>
@@ -144,6 +110,40 @@
context="{'mail':'new', 'model': 'project.issue'}"
icon="gtk-go-forward" type="action" />
</page>
<page string="History" groups="base.group_extended">
<group col="2" colspan="2">
<separator colspan="2" string="Date"/>
<field name="create_date"/>
<field name="write_date" />
<field name="date_closed"/>
<field name="date_open"/>
</group>
<group colspan="2" col="2">
<separator string="Statistics" colspan="2" col="2"/>
<field name="day_open"/>
<field name="day_close"/>
<field name="working_hours_open" widget="float_time"/>
<field name="working_hours_close" widget="float_time"/>
</group>
<group colspan="2" col="2">
<separator string="References" colspan="2"/>
<field name="id"/>
<field name="active"/>
</group>
<field name="log_ids" nolabel="1" colspan="4">
<tree string="Logs">
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</tree>
<form string="Logs">
<separator string="Action Information" colspan="4"/>
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</form>
</field>
</page>
</notebook>
</form>
</field>
@@ -153,7 +153,7 @@
<field name="model">project.issue</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Issue Tracker Tree" colors="red:state=='open';black:state in ('draft', 'cancel','done','pending')">
<tree string="Issue Tracker Tree" colors="red:state=='open';blue:state=='pending';grey:state in ('cancel', 'done')">
<field name="id"/>
<field name="create_date"/>
<field name="name"/>
@@ -186,13 +186,11 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Issue Tracker Search">
<group colspan="4" col="20">
<filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft and Open Issues" icon="terp-check" default="1"/>
<group>
<filter string="Current" name="current" domain="[('state','in',('open','draft'))]" help="Draft and Open Issues" icon="terp-check" default="1"/>
<filter string="In Progress" domain="[('state','=','open')]" help="Open Issues" icon="terp-camera_test"/>
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Issues" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
<filter icon="terp-go-today" string=" Today "
separator="1"
domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"
@@ -204,21 +202,20 @@
help="Bugs during last 7 days"
/>
<separator orientation="vertical"/>
<field name="name" select='1' string="Subject"/>
<field name="user_id" select="1" widget="selection"/>
<field name="state" select="1">
<filter icon="terp-check" domain="[('state','in',('open','draft'))]" help="Current Bugs" name="current_bugs"/>
<filter icon="terp-camera_test" domain="[('state','=','open')]" help="Open Bugs"/>
</field>
<field name="project_id" select="1" widget="selection" string="Project"/>
<field name="name" string="Name"/>
<field name="user_id" widget="selection"/>
<field name="project_id" widget="selection" string="Project"/>
<field name="state"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Project" icon="terp-folder-blue" domain="[]"
context="{'group_by':'project_id'}" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Campaign" icon="terp-gtk-jump-to-rtl"
<filter string="Version" icon="terp-gtk-jump-to-rtl"
domain="[]" context="{'group_by':'type_id'}" />
<separator orientation="vertical" />
<filter string="Partner" icon="terp-personal" domain="[]"
@@ -228,7 +225,6 @@
<separator orientation="vertical" />
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
<separator orientation="vertical" />
</group>
</search>
</field>
@@ -1,3 +1,11 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_project_issue","project.issue","model_project_issue","crm.group_crm_manager",1,1,1,1
"access_project_issue_report","project.issue.report","model_project_issue_report","crm.group_crm_manager",1,0,0,0
"access_project_issue_all","project.issue","model_project_issue","project.group_project_manager",1,1,1,1
"access_project_issue","project.issue","model_project_issue","project_issue.group_project_supporter",1,1,1,1
"access_project_issue_report_all","project.issue.report","model_project_issue_report","project.group_project_manager",1,1,1,1
"access_project_issue_report","project.issue.report","model_project_issue_report","project_issue.group_project_supporter",1,1,1,1
"access_crm_case_categ_id","crm.case.categ","crm.model_crm_case_categ","project.group_project_manager",1,1,1,1
"access_crm_case_categ_supp","crm.case.categ","crm.model_crm_case_categ","project_issue.group_project_supporter",1,0,0,0
"access_crm_case_resource_type_project","crm_case_resource_type manager","crm.model_crm_case_resource_type","project.group_project_manager",1,1,1,1
"access_crm_case_resource_supp","crm_case_resource_type manager","crm.model_crm_case_resource_type","project_issue.group_project_supporter",1,0,0,0
"access_crm_case_stage_project","crm.case.stage","crm.model_crm_case_stage","project.group_project_manager",1,1,1,1
"access_crm_case_stage_manager_suppo","crm.case.stage","crm.model_crm_case_stage","project_issue.group_project_supporter",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_project_issue access_project_issue_all project.issue model_project_issue crm.group_crm_manager project.group_project_manager 1 1 1 1
3 access_project_issue_report access_project_issue project.issue.report project.issue model_project_issue_report model_project_issue crm.group_crm_manager project_issue.group_project_supporter 1 0 1 0 1 0 1
4 access_project_issue_report_all project.issue.report model_project_issue_report project.group_project_manager 1 1 1 1
5 access_project_issue_report project.issue.report model_project_issue_report project_issue.group_project_supporter 1 1 1 1
6 access_crm_case_categ_id crm.case.categ crm.model_crm_case_categ project.group_project_manager 1 1 1 1
7 access_crm_case_categ_supp crm.case.categ crm.model_crm_case_categ project_issue.group_project_supporter 1 0 0 0
8 access_crm_case_resource_type_project crm_case_resource_type manager crm.model_crm_case_resource_type project.group_project_manager 1 1 1 1
9 access_crm_case_resource_supp crm_case_resource_type manager crm.model_crm_case_resource_type project_issue.group_project_supporter 1 0 0 0
10 access_crm_case_stage_project crm.case.stage crm.model_crm_case_stage project.group_project_manager 1 1 1 1
11 access_crm_case_stage_manager_suppo crm.case.stage crm.model_crm_case_stage project_issue.group_project_supporter 1 0 0 0
@@ -2,12 +2,9 @@
<openerp>
<data noupdate="1">
<record id="project_issue_rule" model="ir.rule">
<field name="name">project.issue.rule.group</field>
<field name="model_id" search="[('model','=','project.issue')]" model="ir.model"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('project_id','=',False),('project_id','=',user.context_project_id)]</field>
<record id="group_project_supporter" model="res.groups">
<field name="name">Project / Support Manager</field>
</record>
</data>
</data>
</openerp>
+6 -6
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-11-18 06:10+0000\n"
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
"PO-Revision-Date: 2010-06-09 22:18+0000\n"
"Last-Translator: lyyser <logard.1961@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-04-17 03:58+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: purchase
@@ -606,7 +606,7 @@ msgstr "Kättetoimetamine ja arved"
#. module: purchase
#: field:purchase.order,date_order:0
msgid "Date"
msgstr ""
msgstr "Kuupäev"
#. module: purchase
#: help:purchase.order,origin:0
@@ -666,7 +666,7 @@ msgstr "Kui ostukorraldus on heaks kiidetud, loob see pakkimise nimekirja."
#. module: purchase
#: view:purchase.order.line:0
msgid "History"
msgstr ""
msgstr "Ajalugu"
#. module: purchase
#: field:purchase.order,state:0
@@ -893,4 +893,4 @@ msgstr "Peale ostukorralduse heaks kiitmist läheb see kliendiarveks"
#. module: purchase
#: view:purchase.order.line:0
msgid "Stock Moves"
msgstr ""
msgstr "Lao liikumised"
+5 -5
View File
@@ -7,13 +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-04 12:29+0000\n"
"PO-Revision-Date: 2010-06-09 09:31+0000\n"
"Last-Translator: Jonay <jonay.santana@gmail.com>\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-09 03:36+0000\n"
"X-Launchpad-Export-Date: 2010-06-10 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_task
@@ -205,7 +205,7 @@ msgstr "Cancelado"
#. module: report_task
#: view:report.timesheet.task.user:0
msgid "Timesheet/Task hours Report Per Month"
msgstr ""
msgstr "Horario / Informe de horas de trabajo por mes"
#. module: report_task
#: field:report.task.user.pipeline.open,task_progress:0
@@ -250,7 +250,7 @@ msgstr "Fecha límite"
#. module: report_task
#: field:report.timesheet.task.user,timesheet_hrs:0
msgid "Timesheet Hours"
msgstr ""
msgstr "Horas del horario"
#. module: report_task
#: view:report.closed.task:0
@@ -265,4 +265,4 @@ msgstr "Abrir"
#. module: report_task
#: field:report.closed.task,planned_hours:0
msgid "Planned Hours"
msgstr ""
msgstr "Horas planeadas"
+39 -27
View File
@@ -35,23 +35,23 @@ class sale_advance_payment_inv(osv.osv_memory):
'qtty' : lambda *a: 1
}
def create_invoices(self, cr, uid, ids, context={}):
"""
"""
To create invoices.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
list_inv = []
obj_sale = self.pool.get('sale.order')
obj_lines = self.pool.get('account.invoice.line')
inv_obj = self.pool.get('account.invoice')
for sale_adv_obj in self.browse(cr, uid, ids):
for sale in obj_sale.browse(cr, uid, context['active_ids']):
address_contact = False
@@ -93,7 +93,7 @@ class sale_advance_payment_inv(osv.osv_memory):
'payment_term':sale.payment_term.id,
'fiscal_position': sale.fiscal_position.id or sale.partner_id.property_account_position.id
}
inv_id = inv_obj.create(cr, uid, inv)
for inv in sale.invoice_ids:
@@ -119,6 +119,8 @@ class sale_advance_payment_inv(osv.osv_memory):
'tax_id': [(6, 0, val['value']['invoice_line_tax_id'])],
}, context)
context.update({'invoice_id':list_inv})
return {#'invoice_ids':list_inv,
'name': 'Open Invoice',
'view_type': 'form',
@@ -126,7 +128,7 @@ class sale_advance_payment_inv(osv.osv_memory):
'res_model': 'sale.open.invoice',
'type': 'ir.actions.act_window',
'target': 'new',
'context': "{'invoice_ids'=%s}" % (list_inv)
'context':context
}
sale_advance_payment_inv()
@@ -138,39 +140,49 @@ class sale_open_invoice(osv.osv_memory):
}
def open_invoice(self, cr, uid, ids, context):
"""
"""
To open invoice.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
record_id = context and context.get('active_id', False) or False
mod_obj = self.pool.get('ir.model.data')
obj_inv = self.pool.get('account.invoice')
invoices = []
#TODO: Can not get invoice ids here
invoice = obj_inv.browse(cr, uid, record_id, context=context)
for advance_pay in self.browse(cr, uid, ids):
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
model_data_ids = mod_obj.search(cr, uid,
[('model', '=', 'ir.ui.view'), ('name', '=', 'invoice_form')])
resource_id = mod_obj.read(cr, uid, model_data_ids,
fields=['res_id'])[0]['res_id']
form_id = mod_obj._get_id(cr, uid, 'account', 'invoice_form')
form_res = mod_obj.browse(cr, uid, form_id, context=context).res_id
tree_id = mod_obj._get_id(cr, uid, 'account', 'invoice_tree')
tree_res = mod_obj.browse(cr, uid, tree_id, context=context).res_id
return {
# 'domain': "[('id','in', ["+','.join(map(str, invoices))+"])]", # TODO
'name': 'Invoices',
'view_type': 'form',
'view_mode': 'tree,form',
'view_mode': 'form,tree',
'res_model': 'account.invoice',
'views': [(False, 'tree'), (resource_id, 'form')],
'res_id': int(context['invoice_id'][0]),
'view_id': False,
'views': [(form_res, 'form'), (tree_res, 'tree')],
'context': "{'type':'out_invoice'}",
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
sale_open_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+23 -11
View File
@@ -27,12 +27,12 @@ class product_product(osv.osv):
_inherit = "product.product"
def get_product_accounts(self, cr, uid, product_id, context={}):
def get_product_accounts(self, cr, uid, product_id, context=None):
""" To get the stock input account, stock output account and stock journal related to product.
@param product_id: product id
@return: dictionary which contains information regarding stock input account, stock output account and stock journal
"""
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False)
"""
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, context)
stock_input_acc = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id or False
if not stock_input_acc:
@@ -42,14 +42,15 @@ class product_product(osv.osv):
if not stock_output_acc:
stock_output_acc = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id or False
journal_id = product_obj.categ_id.property_stock_journal and product_obj.categ_id.property_stock_journal.id or False
account_variation = product_obj.categ_id.property_stock_variation and product_obj.categ_id.property_stock_variation.id or False
res = {}
res.update({'stock_account_input': stock_input_acc})
res.update({'stock_account_output': stock_output_acc})
res.update({'stock_journal': journal_id})
return res
return {
'stock_account_input': stock_input_acc,
'stock_account_output': stock_output_acc,
'stock_journal': journal_id,
'property_stock_variation': account_variation
}
def do_change_standard_price(self, cr, uid, ids, datas, context={}):
""" Changes the Standard Price of Product and creates an account move accordingly.
@@ -312,7 +313,14 @@ class product_product(osv.osv):
'track_incoming': fields.boolean('Track Incoming Lots', help="Forces to use a tracking lot during receptions"),
'track_outgoing': fields.boolean('Track Outgoing Lots', help="Forces to use a tracking lot during deliveries"),
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one', domain=[('usage','=','internal')]),
'valuation':fields.selection([('manual_periodic', 'Periodic (manual)'),
('real_time','Real Time (automatized)'),], 'Stock Valuation', help="Decide if the system must automatically creates account moves based on stock moves", required=True),
}
_defaults = {
'valuation': lambda *a: 'manual_periodic',
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
if context == None:
@@ -398,7 +406,6 @@ class product_template(osv.osv):
string='Stock Output Account', method=True, view_load=True,
help='This account will be used, instead of the default one, to value output stock'),
}
product_template()
@@ -417,8 +424,13 @@ class product_category(osv.osv):
type='many2one', relation='account.account',
string='Stock Output Account', method=True, view_load=True,
help='This account will be used to value the output stock'),
'property_stock_variation': fields.property('account.account',
type='many2one',
relation='account.account',
string="Stock variation Account",
method=True, view_load=True,
help="This account will be used in product when valuation type is real-time valuation ",),
}
product_category()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+12
View File
@@ -123,6 +123,18 @@
</field>
</record>
<record id="view_product_valuation_form" model="ir.ui.view">
<field name="name">product.valuation.stock.form.inherit</field>
<field name="model">product.product</field>
<field name="type">form</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="cost_method" position="after">
<field name="valuation"/>
</field>
</field>
</record>
</data>
</openerp>
+75 -71
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
@@ -158,7 +157,7 @@ class stock_location(osv.osv):
_columns = {
'name': fields.char('Location Name', size=64, required=True, translate=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the stock location without removing it."),
'usage': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production')], 'Location Type', required=True),
'usage': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True),
'allocation_method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO'), ('nearest', 'Nearest')], 'Allocation Method', required=True),
'complete_name': fields.function(_complete_name, method=True, type='char', size=100, string="Location Name"),
@@ -195,7 +194,7 @@ class stock_location(osv.osv):
'parent_right': fields.integer('Right Parent', select=1),
'stock_real_value': fields.function(_product_value, method=True, type='float', string='Real Stock Value', multi="stock"),
'stock_virtual_value': fields.function(_product_value, method=True, type='float', string='Virtual Stock Value', multi="stock"),
'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
'company_id': fields.many2one('res.company', 'Company', select=1, help='Let this field empty if this location is shared for every companies'),
'scrap_location': fields.boolean('Scrap Location', help='Check this box if the current location is a place for destroyed items'),
}
_defaults = {
@@ -545,10 +544,11 @@ class stock_picking(osv.osv):
'internal': _('Internal picking'),
'delivery': _('Delivery order')
}
new_id = super(stock_picking, self).create(cr, user, vals, context)
if not vals.get('auto_picking', False):
message = type_list.get(vals.get('type', False), _('Picking')) + " '" + (vals['name'] or "n/a") + "' "+ _("created.")
self.log(cr, user, id, message)
return super(stock_picking, self).create(cr, user, vals, context)
self.log(cr, user, new_id, message)
return new_id
_columns = {
'name': fields.char('Reference', size=64, select=True),
@@ -1737,6 +1737,48 @@ class stock_move(osv.osv):
#self.action_cancel(cr,uid, ids2, context)
return True
def _get_accounting_values(self, cr, uid, move, context=None):
product_obj=self.pool.get('product.product')
product_uom_obj = self.pool.get('product.uom')
price_type_obj = self.pool.get('product.price.type')
accounts = product_obj.get_product_accounts(cr,uid,move.product_id.id,context)
acc_src = accounts['stock_account_input']
acc_dest = accounts['stock_account_output']
acc_variation = accounts['property_stock_variation']
journal_id = accounts['stock_journal']
if not acc_src:
raise osv.except_osv(_('Error!'), _('There is no stock input account defined ' \
'for this product: "%s" (id: %d)') % \
(move.product_id.name, move.product_id.id,))
if not acc_dest:
raise osv.except_osv(_('Error!'), _('There is no stock output account defined ' \
'for this product: "%s" (id: %d)') % \
(move.product_id.name, move.product_id.id,))
if not journal_id:
raise osv.except_osv(_('Error!'), _('There is no journal defined '\
'on the product category: "%s" (id: %d)') % \
(move.product_id.categ_id.name, move.product_id.categ_id.id,))
if not acc_variation:
raise osv.except_osv(_('Error!'), _('There is no variation account defined '\
'on the product category: "%s" (id: %d)') % \
(move.product_id.categ_id.name, move.product_id.categ_id.id,))
if acc_src != acc_dest:
default_uom = move.product_id.uom_id.id
q = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
if move.product_id.cost_method == 'average' and move.price_unit:
amount = q * move.price_unit
# Base computation on valuation price type
else:
company_id = move.company_id.id
context['currency_id'] = move.company_id.currency_id.id
pricetype = price_type_obj.browse(cr,uid,move.company_id.property_valuation_price_type.id)
amount_unit = move.product_id.price_get(pricetype.field, context)[move.product_id.id]
amount = amount_unit * q or 1.0
# amount = q * move.product_id.standard_price
return journal_id, acc_src, acc_dest, acc_variation, amount
def action_done(self, cr, uid, ids, context={}):
""" Makes the move done and if all moves are done, it will finish the picking.
@return:
@@ -1770,76 +1812,38 @@ class stock_move(osv.osv):
#
acc_src = None
acc_dest = None
if move.product_id.valuation=='real_time':
journal_id = move.product_id.categ_id.property_stock_journal and move.product_id.categ_id.property_stock_journal.id or False
accounts=product_obj.get_product_accounts(cr,uid,move.product_id.id,context)
account_variation = move.product_id.categ_id.property_stock_variation.id
acc_src=accounts['stock_account_input']
acc_dest=accounts['stock_account_output']
journal_id=accounts['stock_journal']
if not acc_src:
raise osv.except_osv(_('Error!'),
_('There is no stock input account defined ' \
'for this product: "%s" (id: %d)') % \
(move.product_id.name,
move.product_id.id,))
if not acc_dest:
raise osv.except_osv(_('Error!'),
_('There is no stock output account defined ' \
'for this product: "%s" (id: %d)') % \
(move.product_id.name,
move.product_id.id,))
if not journal_id:
raise osv.except_osv(_('Error!'),
_('There is no journal defined '\
'on the product category: "%s" (id: %d)') % \
(move.product_id.categ_id.name,
move.product_id.categ_id.id,))
if not account_variation:
raise osv.except_osv(_('Error!'),
_('There is no variation account defined '\
'on the product category: "%s" (id: %d)') % \
(move.product_id.categ_id.name,
move.product_id.categ_id.id,))
if acc_src != acc_dest:
default_uom = move.product_id.uom_id.id
q = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
if move.product_id.cost_method == 'average' and move.price_unit:
amount = q * move.price_unit
# Base computation on valuation price type
else:
company_id = move.company_id.id
context['currency_id'] = move.company_id.currency_id.id
pricetype = price_type_obj.browse(cr,uid,move.company_id.property_valuation_price_type.id)
amount_unit = move.product_id.price_get(pricetype.field, context)[move.product_id.id]
amount = amount_unit * q or 1.0
# amount = q * move.product_id.standard_price
partner_id = False
if move.picking_id:
if (move.location_id.usage=='internal' and move.location_dest_id.usage=='customer') or \
(move.location_id.usage=='internal' and move.location_dest_id.usage=='internal'\
and move.location_id.company_id.id!=move.location_dest_id.company_id.id):
sale.append(self.create_account_move(cr,uid,move,acc_dest ,account_variation ,amount,context))
if (move.location_id.usage =='supplier' and move.location_dest_id.usage=='internal') or\
(move.location_id.usage=='internal' and move.location_dest_id.usage=='internal'\
and move.location_id.company_id.id!=move.location_dest_id.company_id.id):
purchase.append(self.create_account_move(cr,uid,move,account_variation, acc_src ,amount,context))
lines.append(purchase and purchase[0] )
lines.append( sale and sale[0])
move_obj.create(cr, uid, {
if move.product_id.valuation == 'real_time':
lines = []
if ((move.location_id.usage == 'internal' and move.location_dest_id.usage == 'customer') or (move.location_id.usage == 'internal' and move.location_dest_id.usage == 'transit')):
if move.location_id.company_id:
context.update({'force_company': move.location_id.company_id.id})
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
lines = [(journal_id, self.create_account_move(cr, uid, move, acc_dest, acc_variation, amount, context))]
elif ((move.location_id.usage == 'supplier' and move.location_dest_id.usage == 'internal') or (move.location_id.usage == 'transit' and move.location_dest_id.usage == 'internal')):
if move.location_dest_id.company_id:
context.update({'force_company': move.location_dest_id.company_id.id})
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
lines = [(journal_id, self.create_account_move(cr, uid, move, acc_variation, acc_src, amount, context))]
elif (move.location_id.usage == 'internal' and move.location_dest_id.usage == 'internal' and move.location_id.company_id != move.location_dest_id.company_id):
if move.location_id.company_id:
context.update({'force_company': move.location_id.company_id.id})
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
line1 = [(journal_id, self.create_account_move(cr, uid, move, acc_dest, acc_variation, amount, context))]
if move.location_dest_id.company_id:
context.update({'force_company': move.location_dest_id.company_id.id})
journal_id, acc_src, acc_dest, acc_variation, amount = self._get_accounting_values(cr, uid, move, context)
line2 = [(journal_id, self.create_account_move(cr, uid, move, acc_variation, acc_src, amount, context))]
lines = line1 + line2
for j_id, line in lines:
move_obj.create(cr, uid, {
'name': move.name,
'journal_id': journal_id,
'journal_id': j_id,
'type':'cont_voucher',
'line_id': len(lines)==2 and lines[0] +lines[1] or lines,
'line_id': line,
'ref': move.picking_id and move.picking_id.name,
})
})
tracking_lot = False
if context:
tracking_lot = context.get('tracking_lot', False)
+7 -1
View File
@@ -288,7 +288,13 @@
<field name="company_id" ref="res_company_tinyshop0"/>
<field name="lot_input_id" ref="stock_location_shop1"/>
</record>
<record forcecreate="True" id="property_stock_variation" model="ir.property">
<field name="name">property_stock_variation</field>
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_variation')]"/>
<field eval="'account.account,'+str(ref('account.a_recv'))" model="account.account" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
</data>
</openerp>
+1 -1
View File
@@ -73,7 +73,7 @@ class procurement_order(osv.osv):
'move_type': 'one',
'address_id': line.partner_address_id.id,
'note': line.name, # TODO: note on procurement ?
'invoice_state': 'none',
'invoice_state': line.invoice_state,
})
move_id = self.pool.get('stock.move').create(cr, uid, {
'name': line.name,
+14 -1
View File
@@ -33,6 +33,12 @@ class stock_location_path(osv.osv):
'location_from_id' : fields.many2one('stock.location', 'Source Location', ondelete='cascade', select=1),
'location_dest_id' : fields.many2one('stock.location', 'Destination Location', ondelete='cascade', select=1),
'delay': fields.integer('Delay (days)', help="Number of days to do this transition"),
'invoice_state': fields.selection([
("invoiced", "Invoiced"),
("2binvoiced", "To Be Invoiced"),
("none", "Not from Picking")], "Invoice Status",
required=True,),
'picking_type': fields.selection([('out','Sending Goods'),('in','Getting Goods'),('internal','Internal'),('delivery','Delivery')], 'Shipping Type', required=True, select=True, help="Depending on the company, choose whatever you want to receive or send products"),
'auto': fields.selection(
[('auto','Automatic Move'), ('manual','Manual Operation'),('transparent','Automatic No Step Added')],
'Automatic Move',
@@ -45,7 +51,8 @@ class stock_location_path(osv.osv):
}
_defaults = {
'auto': lambda *arg: 'auto',
'delay': lambda *arg: 1
'delay': lambda *arg: 1,
'invoice_state': lambda *args: 'none',
}
stock_location_path()
@@ -63,12 +70,18 @@ class product_pulled_flow(osv.osv):
'partner_address_id': fields.many2one('res.partner.address', 'Partner Address'),
'picking_type': fields.selection([('out','Sending Goods'),('in','Getting Goods'),('internal','Internal'),('delivery','Delivery')], 'Shipping Type', required=True, select=True, help="Depending on the company, choose whatever you want to receive or send products"),
'product_id':fields.many2one('product.product','Product'),
'invoice_state': fields.selection([
("invoiced", "Invoiced"),
("2binvoiced", "To Be Invoiced"),
("none", "Not from Picking")], "Invoice Status",
required=True,),
}
_defaults = {
'cancel_cascade': lambda *arg: False,
'procure_method': lambda *args: 'make_to_stock',
'type_proc': lambda *args: 'move',
'picking_type':lambda *args:'out',
'invoice_state': lambda *args: 'none',
}
product_pulled_flow()
+2
View File
@@ -63,6 +63,7 @@
<field name="partner_address_id"/>
<field name="procure_method"/>
<field name="cancel_cascade"/>
<field name="invoice_state"/>
</group>
</form>
</field>
@@ -74,6 +75,7 @@
<field name="auto"/>
<field name="delay"/>
<field name="name"/>
<field name="invoice_state"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
+22 -11
View File
@@ -130,19 +130,23 @@
string="Basic Wiki Editing" icon="gtk-ok" />
</group>
<group col="8" colspan="4">
<field name="group_id" select="1" on_change="onchange_group_id(group_id, text_area)"/>
<field name="group_id" string="Topic" select="1" on_change="onchange_group_id(group_id, text_area)"/>
<field name="section" invisible="not context.get('section',False)"/>
<field name="parent_id"/>
<!-- <field name="parent_id"/>-->
</group>
<separator colspan="4" string="Informations"/>
<field name="text_area" nolabel="1" colspan="4" select="1" widget="text_wiki"/>
<notebook colspan="4">
<page string="Content">
<separator colspan="4" string="Informations"/>
<field name="text_area" nolabel="1" colspan="4" select="1" widget="text_wiki"/>
</page>
</notebook>
<separator colspan="4" string="Modifications"/>
<group col="6" colspan="4">
<group col="4" colspan="4">
<field name="write_date" readonly="1"/>
<field name="review" select="1"/>
<field name="toc"/>
<field name="tags" select="1" groups="base.group_extended"/>
<field name="summary" colspan="4" groups="base.group_extended"/>
<field name="toc"/>
<!-- <field name="summary" colspan="4" groups="base.group_extended"/>-->
</group>
</form>
</field>
@@ -156,13 +160,20 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Wiki">
<group col='8' colspan='4'>
<filter icon="terp-check" string="Need Review" domain="[('review','=',True)]"/>
<separator orientation="vertical"/>
<field name="section" select="1"/>
<field name="name" select="1"/>
<field name="group_id" select="1"/>
<field name="text_area" select="1"/>
<field name="write_uid" select="1"/>
<field name="write_date" select="1"/>
<field name="review" select="1"/>
<field name="create_uid" widget="selection" select="1"/>
<!-- <field name="create_uid" widget="selection" select="1"/>-->
<newline/>
<group expand="0" string="Group By..." colspan="8" col="6">
<filter icon="terp-check" string="Wiki Group" domain="[]" context="{'group_by':'group_id'}"/>
<filter icon="terp-personal" string="Author" domain="[]" context="{'group_by':'create_uid'}"/>
<filter icon="terp-personal-" string="Last Author" domain="[]" context="{'group_by':'write_uid'}"/>
</group>
</search>
</field>
@@ -176,7 +187,7 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_wiki_tree"/>
<field name="context">{'section':'1','search_default_create_uid':uid}</field>
<!-- <field name="context">{'section':'1','search_default_create_uid':uid}</field>-->
<field name="search_view_id" ref="view_wiki_filter"/>
</record>