[REF] subscription: migration into the new api
This commit is contained in:
committed by
Martin Trigaux
parent
29fe0353e3
commit
46401a2a4a
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" ?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field eval="[(4, ref('base.group_sale_salesman'))]" name="groups_id"/>
|
||||
</record>
|
||||
@@ -19,5 +18,4 @@
|
||||
<field name="field" ref="base.field_res_partner_child_ids"/>
|
||||
<field model="subscription.document" name="document_id" search="[('name', '=', u'Partner')]"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -4,147 +4,128 @@
|
||||
# TODO:
|
||||
# Error treatment: exception, request, ... -> send request to user_id
|
||||
|
||||
import time
|
||||
from openerp.osv import fields,osv
|
||||
from openerp.tools.translate import _
|
||||
from openerp.exceptions import UserError
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
class subscription_document(osv.osv):
|
||||
|
||||
def _get_document_types(self):
|
||||
return [(doc.model.model, doc.name) for doc in self.env['subscription.document'].search([], order='name')]
|
||||
|
||||
|
||||
class SubscriptionDocument(models.Model):
|
||||
_name = "subscription.document"
|
||||
_description = "Subscription Document"
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the subscription document without removing it."),
|
||||
'model': fields.many2one('ir.model', 'Object', required=True),
|
||||
'field_ids': fields.one2many('subscription.document.fields', 'document_id', 'Fields', copy=True)
|
||||
}
|
||||
_defaults = {
|
||||
'active' : lambda *a: True,
|
||||
}
|
||||
|
||||
class subscription_document_fields(osv.osv):
|
||||
name = fields.Char(required=True)
|
||||
active = fields.Boolean(help="If the active field is set to False, it will allow you to hide the subscription document without removing it.", default=True)
|
||||
model = fields.Many2one('ir.model', string="Object", required=True)
|
||||
field_ids = fields.One2many('subscription.document.fields', 'document_id', string='Fields', copy=True)
|
||||
|
||||
|
||||
class SubscriptionDocumentFields(models.Model):
|
||||
_name = "subscription.document.fields"
|
||||
_description = "Subscription Document Fields"
|
||||
_rec_name = 'field'
|
||||
_columns = {
|
||||
'field': fields.many2one('ir.model.fields', 'Field', domain="[('model_id', '=', parent.model)]", required=True),
|
||||
'value': fields.selection([('false','False'),('date','Current Date')], 'Default Value', size=40, help="Default value is considered for field when new document is generated."),
|
||||
'document_id': fields.many2one('subscription.document', 'Subscription Document', ondelete='cascade'),
|
||||
}
|
||||
_defaults = {}
|
||||
|
||||
def _get_document_types(self, cr, uid, context=None):
|
||||
cr.execute('select m.model, s.name from subscription_document s, ir_model m WHERE s.model = m.id order by s.name')
|
||||
return cr.fetchall()
|
||||
field = fields.Many2one('ir.model.fields', domain="[('model_id', '=', parent.model)]", required=True)
|
||||
value = fields.Selection([('false', 'False'), ('date', 'Current Date')], string='Default Value', help="Default value is considered for field when new document is generated.")
|
||||
document_id = fields.Many2one('subscription.document', string='Subscription Document', ondelete='cascade')
|
||||
|
||||
class subscription_subscription(osv.osv):
|
||||
|
||||
class Subscription(models.Model):
|
||||
_name = "subscription.subscription"
|
||||
_description = "Subscription"
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the subscription without removing it."),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'notes': fields.text('Internal Notes'),
|
||||
'user_id': fields.many2one('res.users', 'User', required=True),
|
||||
'interval_number': fields.integer('Interval Qty'),
|
||||
'interval_type': fields.selection([('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], 'Interval Unit'),
|
||||
'exec_init': fields.integer('Number of documents'),
|
||||
'date_init': fields.datetime('First Date'),
|
||||
'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'Status', copy=False),
|
||||
'doc_source': fields.reference('Source Document', required=True, selection=_get_document_types, size=128, help="User can choose the source document on which he wants to create documents"),
|
||||
'doc_lines': fields.one2many('subscription.subscription.history', 'subscription_id', 'Documents created', readonly=True),
|
||||
'cron_id': fields.many2one('ir.cron', 'Cron Job', help="Scheduler which runs on subscription", states={'running':[('readonly',True)], 'done':[('readonly',True)]}),
|
||||
'note': fields.text('Notes', help="Description or Summary of Subscription"),
|
||||
}
|
||||
_defaults = {
|
||||
'date_init': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'user_id': lambda obj,cr,uid,context: uid,
|
||||
'active': lambda *a: True,
|
||||
'interval_number': lambda *a: 1,
|
||||
'interval_type': lambda *a: 'months',
|
||||
'doc_source': lambda *a: False,
|
||||
'state': lambda *a: 'draft'
|
||||
}
|
||||
|
||||
def _auto_end(self, cr, context=None):
|
||||
super(subscription_subscription, self)._auto_end(cr, context=context)
|
||||
name = fields.Char(required=True)
|
||||
active = fields.Boolean(help="If the active field is set to False, it will allow you to hide the subscription without removing it.", default=True)
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
notes = fields.Text(string='Internal Notes')
|
||||
user_id = fields.Many2one('res.users', string='User', required=True, default=lambda self: self.env.user)
|
||||
interval_number = fields.Integer(string='Internal Qty', default=1)
|
||||
interval_type = fields.Selection([('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], string='Interval Unit', default='months')
|
||||
exec_init = fields.Integer(string='Number of Documents')
|
||||
date_init = fields.Datetime(string='First Date', default=fields.Datetime.now)
|
||||
state = fields.Selection([('draft', 'Draft'), ('running', 'Running'), ('done', 'Done')], string='Status', copy=False, default='draft')
|
||||
doc_source = fields.Reference(selection=_get_document_types, string='Source Document', required=True, help="User can choose the source document on which he wants to create documents")
|
||||
doc_lines = fields.One2many('subscription.subscription.history', 'subscription_id', string='Documents created', readonly=True)
|
||||
cron_id = fields.Many2one('ir.cron', string='Cron Job', help="Scheduler which runs on subscription", states={'running': [('readonly', True)], 'done': [('readonly', True)]})
|
||||
note = fields.Text(string='Notes', help="Description or Summary of Subscription")
|
||||
|
||||
@api.model
|
||||
def _auto_end(self):
|
||||
super(Subscription, self)._auto_end()
|
||||
# drop the FK from subscription to ir.cron, as it would cause deadlocks
|
||||
# during cron job execution. When model_copy() tries to write() on the subscription,
|
||||
# it has to wait for an ExclusiveLock on the cron job record, but the latter
|
||||
# it has to wait for an ExclusiveLock on the cron job record, but the latter
|
||||
# is locked by the cron system for the duration of the job!
|
||||
# FIXME: the subscription module should be reviewed to simplify the scheduling process
|
||||
# and to use a unique cron job for all subscriptions, so that it never needs to
|
||||
# be updated during its execution.
|
||||
cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (self._table, '%s_cron_id_fkey' % self._table))
|
||||
# be updated during its execution.
|
||||
self.env.cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (self._table, '%s_cron_id_fkey' % self._table))
|
||||
|
||||
def set_process(self, cr, uid, ids, context=None):
|
||||
for row in self.read(cr, uid, ids, context=context):
|
||||
mapping = {'name':'name','interval_number':'interval_number','interval_type':'interval_type','exec_init':'numbercall','date_init':'nextcall'}
|
||||
res = {'model':'subscription.subscription', 'args': repr([[row['id']]]), 'function':'model_copy', 'priority':6, 'user_id':row['user_id'] and row['user_id'][0]}
|
||||
for key,value in mapping.items():
|
||||
res[value] = row[key]
|
||||
id = self.pool.get('ir.cron').create(cr, uid, res)
|
||||
self.write(cr, uid, [row['id']], {'cron_id':id, 'state':'running'})
|
||||
return True
|
||||
@api.multi
|
||||
def set_process(self):
|
||||
for subscription in self:
|
||||
cron_data = {
|
||||
'name': subscription.name,
|
||||
'interval_number': subscription.interval_number,
|
||||
'interval_type': subscription.interval_type,
|
||||
'numbercall': subscription.exec_init,
|
||||
'nextcall': subscription.date_init,
|
||||
'model': self._name,
|
||||
'args': repr([[subscription.id]]),
|
||||
'function': 'model_copy',
|
||||
'priority': 6,
|
||||
'user_id': subscription.user_id.id
|
||||
}
|
||||
cron = self.env['ir.cron'].create(cron_data)
|
||||
subscription.write({'cron_id': cron.id, 'state': 'running'})
|
||||
|
||||
def model_copy(self, cr, uid, ids, context=None):
|
||||
for row in self.read(cr, uid, ids, context=context):
|
||||
if not row.get('cron_id',False):
|
||||
continue
|
||||
cron_ids = [row['cron_id'][0]]
|
||||
remaining = self.pool.get('ir.cron').read(cr, uid, cron_ids, ['numbercall'])[0]['numbercall']
|
||||
try:
|
||||
(model_name, id) = row['doc_source'].split(',')
|
||||
id = int(id)
|
||||
model = self.pool[model_name]
|
||||
except:
|
||||
@api.multi
|
||||
def model_copy(self):
|
||||
for subscription in self.filtered(lambda sub: sub.cron_id):
|
||||
if not subscription.doc_source.exists():
|
||||
raise UserError(_('Please provide another source document.\nThis one does not exist!'))
|
||||
|
||||
default = {'state':'draft'}
|
||||
doc_obj = self.pool.get('subscription.document')
|
||||
document_ids = doc_obj.search(cr, uid, [('model.model','=',model_name)])
|
||||
doc = doc_obj.browse(cr, uid, document_ids)[0]
|
||||
for f in doc.field_ids:
|
||||
if f.value=='date':
|
||||
value = time.strftime('%Y-%m-%d')
|
||||
else:
|
||||
value = False
|
||||
default[f.field.name] = value
|
||||
|
||||
state = 'running'
|
||||
default = {'state': 'draft'}
|
||||
documents = self.env['subscription.document'].search([('model.model', '=', subscription.doc_source._name)], limit=1)
|
||||
fieldnames = dict((f.field.name, f.value == 'date' and fields.Date.today() or False)
|
||||
for f in documents.field_ids)
|
||||
default.update(fieldnames)
|
||||
|
||||
# if there was only one remaining document to generate
|
||||
# the subscription is over and we mark it as being done
|
||||
if remaining == 1:
|
||||
state = 'done'
|
||||
id = self.pool[model_name].copy(cr, uid, id, default, context)
|
||||
self.pool.get('subscription.subscription.history').create(cr, uid, {'subscription_id': row['id'], 'date':time.strftime('%Y-%m-%d %H:%M:%S'), 'document_id': model_name+','+str(id)})
|
||||
self.write(cr, uid, [row['id']], {'state':state})
|
||||
return True
|
||||
if subscription.cron_id.numbercall == 1:
|
||||
subscription.write({'state': 'done'})
|
||||
else:
|
||||
subscription.write({'state': 'running'})
|
||||
copied_doc = subscription.doc_source.copy(default)
|
||||
self.env['subscription.subscription.history'].create({
|
||||
'subscription_id': subscription.id,
|
||||
'date': fields.Datetime.now(),
|
||||
'document_id': '%s,%s' % (subscription.doc_source._name, copied_doc.id)})
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for record in self.browse(cr, uid, ids, context or {}):
|
||||
if record.state=="running":
|
||||
raise UserError(_('You cannot delete an active subscription!'))
|
||||
return super(subscription_subscription, self).unlink(cr, uid, ids, context)
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
if any(self.filtered(lambda s: s.state == "running")):
|
||||
raise UserError(_('You cannot delete an active subscription!'))
|
||||
return super(Subscription, self).unlink()
|
||||
|
||||
def set_done(self, cr, uid, ids, context=None):
|
||||
res = self.read(cr,uid, ids, ['cron_id'])
|
||||
ids2 = [x['cron_id'][0] for x in res if x['id']]
|
||||
self.pool.get('ir.cron').write(cr, uid, ids2, {'active':False})
|
||||
self.write(cr, uid, ids, {'state':'done'})
|
||||
return True
|
||||
@api.multi
|
||||
def set_done(self):
|
||||
self.mapped('cron_id').write({'active': False})
|
||||
self.write({'state': 'done'})
|
||||
|
||||
def set_draft(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'state':'draft'})
|
||||
return True
|
||||
@api.multi
|
||||
def set_draft(self):
|
||||
self.write({'state': 'draft'})
|
||||
|
||||
class subscription_subscription_history(osv.osv):
|
||||
|
||||
class SubscriptionHistory(models.Model):
|
||||
_name = "subscription.subscription.history"
|
||||
_description = "Subscription history"
|
||||
_rec_name = 'date'
|
||||
_columns = {
|
||||
'date': fields.datetime('Date'),
|
||||
'subscription_id': fields.many2one('subscription.subscription', 'Subscription', ondelete='cascade'),
|
||||
'document_id': fields.reference('Source Document', required=True, selection=_get_document_types, size=128),
|
||||
}
|
||||
|
||||
date = fields.Datetime()
|
||||
subscription_id = fields.Many2one('subscription.subscription', string='Subscription', ondelete='cascade')
|
||||
document_id = fields.Reference(selection=_get_document_types, string='Source Document', required=True)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<!-- Subscription Views -->
|
||||
<record id="view_subscription_form" model="ir.ui.view">
|
||||
@@ -186,5 +185,4 @@
|
||||
</record>
|
||||
<menuitem id="menu_action_document_form" action="action_document_form" parent="base.menu_automation"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user