653
655
training_offer_format()
655
class training_offer_purchase_line_update_wizard(osv.osv_memory):
656
_name = 'training.offer.purchase.line.update.wizard'
658
'name': fields.char('Summary', size=256),
659
'log': fields.text('Log Text'),
660
'date': fields.datetime('Date'),
661
'state': fields.selection([('confirm','Confirm'),('update','Update')]),
665
'state': lambda *a: 'confirm',
668
def action_cancel(self, cr, uid, ids, context=None):
669
return {'type': 'ir.actions.act_window_close' }
671
def action_close(self, cr, uid, ids, context=None):
672
return {'type': 'ir.actions.act_window_close' }
674
def action_confirm(self, cr, uid, ids, context=None):
675
offer_proxy = self.pool.get('training.offer')
676
offer_id = context.get('active_id', False)
677
val = offer_proxy.action_update_seance_procurements(cr, uid, offer_id, context=context)
679
val['state'] = 'update'
681
val = { 'name': _('FAILED')}
682
return self.write(cr, uid, ids, val, context=context)
684
training_offer_purchase_line_update_wizard()
686
658
class training_offer_purchase_line_log(osv.osv):
687
659
_name = 'training.offer.purchase.line.log'
1163
1117
training_catalog()
1165
def get_zip_from_directory(directory, b64enc=True):
1166
RE_exclude = re.compile('(?:^\..+\.swp$)|(?:\.py[oc]$)|(?:\.bak$)|(?:\.~.~$)', re.I)
1168
def _zippy(archive, path):
1169
path = os.path.abspath(path)
1170
base = os.path.basename(path)
1171
for f in tools.osutil.listdir(path, True):
1172
bf = os.path.basename(f)
1173
if not RE_exclude.search(bf):
1174
archive.write(os.path.join(path, f), os.path.join(base, f))
1176
archname = StringIO()
1177
archive = PyZipFile(archname, "w", ZIP_DEFLATED)
1178
archive.writepy(directory)
1179
_zippy(archive, directory)
1181
val = archname.getvalue()
1185
val = base64.encodestring(val)
1189
class training_seance_generate_pdf_wizard(osv.osv_memory):
1190
_name = 'training.seance.generate.zip.wizard'
1193
'presence_list_report' : fields.boolean('Presence List Report',
1194
help="If you select this option you will print the report for the presence list. " \
1195
"The file format is Presence_List_DATEOFSEANCE_SEANCEID.pdf."),
1196
'remuneration_form_report' : fields.boolean('Remuneration Form',
1197
help="If you select this option, you will print the report for the remuneration " \
1198
"forms of all contacts. The file format is Request_REQUESTNAME_Invoice_INVOICEID.pdf."),
1199
'zip_file' : fields.binary('Zip File', readonly=True),
1200
'zip_file_name' : fields.char('File name', readonly=True, size=64),
1201
'state' : fields.selection( [ ('selection', 'Selection'), ('result', 'Result') ], 'State', readonly=True, required=True),
1205
'presence_list_report' : lambda *a: 0,
1206
'remuneration_form_report' : lambda *a: 0,
1207
'state' : lambda *a: 'selection',
1210
def action_close(self, cr, uid, ids, context=None):
1211
return { 'type' : 'ir.actions.act_window.close' }
1213
def action_generate_zip(self, cr, uid, ids, context=None):
1216
parent_directory = tempfile.mkdtemp(prefix='openerp_', suffix='_reports')
1217
directory = os.path.join(parent_directory, 'Reports')
1219
self.add_selections(cr, uid, ids, directory, context=context)
1220
result = get_zip_from_directory(directory, True)
1221
fp = file(os.path.join(parent_directory, 'output.zip'), 'w')
1225
active_id = context and context.get('active_id')
1226
seance = self.pool.get('training.seance').browse(cr, uid, active_id, context=context)
1227
ts = time.strptime(seance.date, '%Y-%m-%d %H:%M:%S')
1228
date = time.strftime('%Y%m%d', ts)
1232
'zip_file' : result,
1233
'zip_file_name' : 'Seance_Reports_%s_%06d.zip' % (date, seance.id),
1237
shutil.rmtree(parent_directory)
1238
return self.write(cr, uid, ids, values, context=context)
1240
def _get_report(self, cr, uid, oid, reportname, context=None):
1241
srv = netsvc.LocalService(reportname)
1242
pdf, _ = srv.create(cr, uid, [oid], {}, context=context)
1245
def add_selections(self, cr, uid, ids, directory, context=None):
1246
active_id = context and context.get('active_id')
1247
seance = self.pool.get('training.seance').browse(cr, uid, active_id, context=context)
1248
ts = time.strptime(seance.date, '%Y-%m-%d %H:%M:%S')
1249
date = time.strftime('%Y%m%d', ts)
1250
for obj in self.browse(cr, uid, ids, context=context):
1251
if obj.presence_list_report:
1252
res = self._get_report(cr, uid, active_id, 'report.training.seance.presence.report', context=context)
1253
filename = os.path.join(directory, 'Presence_List_%s_%06d.pdf' % (date, seance.id,))
1254
fp = file(filename, 'w')
1258
if obj.remuneration_form_report:
1259
for contact in seance.contact_ids:
1260
if not contact.request_id:
1261
raise osv.except_osv(_('Error'),
1262
_('The stakeholder %s %s has not a request') % (contact.job_id.fist_name, contact.job_id.name) )
1264
if not contact.request_id.purchase_order_id:
1265
raise osv.except_osv(_('Error'),
1266
_('There is no Purchase Order for a request'))
1268
if not contact.request_id.purchase_order_id.invoice_id:
1269
raise osv.except_osv(_('Error'),
1270
_('There is no Invoice for the Purchase Order for this request'))
1272
res = self._get_report(cr, uid, contact.request_id.purchase_order_id.invoice_id.id, 'report.account.invoice', context=context)
1273
filename = os.path.join(directory, 'Request_%s_Invoice_%06d.pdf' % (re.sub('/|-', '_', contact.request_id.reference),
1274
contact.request_id.purchase_order_id.invoice_id.id))
1275
fp = file(filename, 'w')
1279
training_seance_generate_pdf_wizard()
1281
1120
class training_seance(osv.osv):
1282
1121
_name = 'training.seance'
1579
1418
for seance in session.seance_ids:
1580
1419
if seance.date < session.date:
1423
def _check_date_end_of_seances(self, cr, uid, ids, context=None):
1424
for session in self.browse(cr, uid, ids, context=context):
1425
for seance in session.seance_ids:
1426
if session.date_end and seance.date > session.date_end:
1585
1430
_constraints = [
1586
1431
#(_check_date_before_now, "You cannot create a date before now", ['date']),
1587
1432
#(_check_date_holiday, "You cannot assign a date in a public holiday", ['date']),
1588
(_check_date_of_seances, "You have a seance with a date inferior to the session's date", ['date']),
1433
(_check_date_of_seances, "You have a seance with a date inferior to the session's date.", ['date']),
1434
(_check_date_end_of_seances, "You have a seance with a later date to the session's end date.", ['date_end']),
1591
1437
def _find_catalog_id(self, cr, uid, context=None):
2064
1910
training_session()
2066
class training_subscription_mass_wizard(osv.osv_memory):
2067
_name = 'training.subscription.mass.wizard'
2068
_description = 'Mass Subscription Wizard'
2070
def action_cancel(self, cr, uid, ids, context=None):
2071
return {'type':'ir.actions.act_window_close'}
2073
def action_apply(self, cr, uid, ids, context=None):
2074
subscription_form_view = context and context.get('subscription_form_view', False) or False
2075
record_id = context and context.get('record_id', False) or False
2077
this = self.browse(cr, uid, ids)[0]
2079
subscription_proxy = self.pool.get('training.subscription')
2080
subscription_line_proxy = self.pool.get('training.subscription.line')
2081
subscription_line_second_proxy = self.pool.get('training.subscription.line.second')
2086
for job in this.job_ids:
2087
for subscription_mass_line in this.session_ids:
2088
sl_id = subscription_line_proxy._create_from_wizard(cr, uid, this, record_id, job, subscription_mass_line, context=context)
2091
'type' : 'ir.actions.act_window_close',
2094
for job in this.job_ids:
2095
# if the job hasn't a partner, we put this subscription in waiting mode
2097
for subscription_mass_line in this.session_ids:
2098
subscription_line_second_proxy._create_from_wizard(cr, uid, this, job, subscription_mass_line, context=context)
2101
for subscription_mass_line in this.session_ids:
2102
subscriptions.setdefault(job.name.id, []).append((job, subscription_mass_line,))
2104
subscription_ids = []
2106
# We create all subscription where there is a partner associated to the job
2107
for partner_id, lines in subscriptions.iteritems():
2108
values = subscription_proxy.on_change_partner(cr, uid, [], partner_id)['value']
2110
'partner_id' : partner_id,
2113
subscription_id = subscription_proxy.create(cr, uid, values, context=context)
2115
for job, subscription_mass_line in lines:
2116
subscription_line_proxy._create_from_wizard(cr, uid, this, subscription_id, job, subscription_mass_line, context=context)
2118
subscription_ids.append(subscription_id)
2120
mod_id = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'training_subscription_all_act')])[0]
2121
res_id = self.pool.get('ir.model.data').read(cr, uid, mod_id, ['res_id'])['res_id']
2122
act_win = self.pool.get('ir.actions.act_window').read(cr, uid, res_id, [])
2123
act_win['domain'] = [('id','in',subscription_ids)]
2124
act_win['name'] = _('Subscriptions')
2129
'partner_id' : fields.many2one('res.partner', 'Partner'),
2130
'job_ids' : fields.many2many('res.partner.job',
2131
'tms_contact_job_rel',
2136
'session_ids' : fields.one2many('training.subscription.mass.line', 'wizard_id', 'Sessions'),
2139
def default_get(self, cr, uid, fields, context=None):
2140
record_id = context and context.get('record_id', False) or False
2142
res = super(training_subscription_mass_wizard, self).default_get(cr, uid, fields, context=context)
2145
partner_id = self.pool.get('training.subscription').browse(cr, uid, record_id, context=context).partner_id.id
2146
res['partner_id'] = partner_id
2150
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
2151
record_id = context and context.get('record_id', False) or False
2153
res = super(training_subscription_mass_wizard, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
2155
if 'fields' in res and 'partner_id' in res['fields']:
2156
res['fields']['partner_id']['readonly'] = True
2160
training_subscription_mass_wizard()
2162
class mass_subscription_line(osv.osv_memory):
2163
_name = 'training.subscription.mass.line'
2166
'wizard_id' : fields.many2one('training.subscription.mass.wizard', 'Wizard'),
2167
'session_id' : fields.many2one('training.session', 'Session',
2168
domain="[('state', 'in', ('opened','opened_confirmed', 'closed_confirmed', 'inprogress'))]", required=True),
2169
'allow_closed_session': fields.boolean('Allow Closed Session'),
2170
'kind' : fields.related('session_id','offer_id', 'kind',
2172
selection=training_offer_kind_compute,
2177
def on_change_allow_closed_session(self, cr, uid, ids, new_allow, context=None):
2180
'domain': {'session_id': []}
2184
'domain': {'session_id': [('state', 'in', ('opened','opened_confirmed', 'closed_confirmed', 'inprogress'))]}
2188
def on_change_session(self, cr, uid, ids, context=None):
2191
mass_subscription_line()
2193
1913
class training_subscription_line_second(osv.osv):
2194
1914
_name = 'training.subscription.line.second'
2268
1988
'training.subscription.line': (_store_get_sublines, None, 10),
2271
'contact_lastname': fields.related('contact_id', 'name', readonly=True, type='char', size=64, string='Contact Last Name',
1991
'contact_lastname': fields.related('subscription_line_id', 'job_id', 'contact_id', 'name', readonly=True, type='char', size=64, string='Contact Last Name',
2273
1993
'training.subscription.line': (_store_get_sublines, None, 11),
2276
'contact_firstname': fields.related('contact_id', 'first_name', readonly=True, type='char', size=64, string='Contact First Name',
1996
'contact_firstname': fields.related('subscription_line_id', 'job_id', 'contact_id', 'first_name', readonly=True, type='char', size=64, string='Contact First Name',
2278
1998
'training.subscription.line': (_store_get_sublines, None, 11),
3282
3002
'was_present': fields.function(_was_present_compute, method=True, type='boolean', string='Was Present'),
3285
def _default_name(self, cr, uid, context=None):
3286
return self.pool.get('ir.sequence').get(cr, uid, 'training.subscription.line')
3005
def create(self, cr, uid, vals, context):
3006
if vals.get('name', '/')=='/':
3007
vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'training.subscription.line')
3008
return super(training_subscription_line, self).create(cr, uid, vals, context)
3288
3010
def unlink(self, cr, uid, vals, context):
3289
3011
subscription_lines = self.read(cr, uid, vals, ['state'])
4524
4245
training_course_pending()
4526
class training_course_pending_wizard(osv.osv_memory):
4527
_name = 'training.course.pending.wizard'
4530
'course_id' : fields.many2one('training.course', 'Course'),
4531
'type' : fields.selection(training_course_pending_reason_compute,
4535
'date' : fields.date('Planned Date'),
4536
'reason' : fields.text('Reason'),
4537
'job_id' : fields.many2one('res.partner.job', 'Contact', required=True),
4538
'state' : fields.selection([('first_screen', 'First Screen'),
4539
('second_screen', 'Second Screen')],
4544
'type' : lambda *a: 'update_support',
4545
'state' : lambda *a: 'first_screen',
4546
'course_id' : lambda obj, cr, uid, context: context.get('active_id', 0)
4549
def action_cancel(self, cr, uid, ids, context=None):
4550
return {'type' : 'ir.actions.act_window_close'}
4552
def action_apply(self, cr, uid, ids, context=None):
4553
course_id = context and context.get('active_id', False) or False
4558
this = self.browse(cr, uid, ids)[0]
4560
workflow = netsvc.LocalService('workflow')
4561
workflow.trg_validate(uid, 'training.course', course_id, 'signal_pending', cr)
4564
'course_id' : course_id,
4567
'reason' : this.reason,
4568
'job_id' : this.job_id and this.job_id.id,
4571
self.pool.get('training.course.pending').create(cr, uid, values, context=context)
4573
return {'res_id' : course_id}
4575
training_course_pending_wizard()
4578
4248
class training_contact_course(osv.osv):
4579
4249
_name = 'training.contact.course'
4604
4274
res_partner_contact()
4606
class training_session_duplicate_wizard(osv.osv_memory):
4607
_name = 'training.session.duplicate.wizard'
4610
'session_id': fields.many2one('training.session', 'Session',
4613
domain=[('state', 'in', ['opened', 'opened_confirmed'])]),
4614
'group_id' : fields.many2one('training.group', 'Group',
4615
domain="[('session_id', '=', session_id)]"),
4616
'subscription_line_ids' : fields.many2many('training.subscription.line',
4617
'training_sdw_participation_rel',
4621
domain="[('session_id', '=', session_id),('state', '=', 'confirmed')]"),
4624
def action_cancel(self, cr, uid, ids, context=None):
4625
return {'type' : 'ir.actions.act_window_close'}
4627
def action_apply(self, cr, uid, ids, context=None):
4628
this = self.browse(cr, uid, ids[0], context=context)
4630
if len(this.subscription_line_ids) == 0:
4631
raise osv.except_osv(_('Error'),
4632
_('You have not selected a participant of this session'))
4636
if any(len(seance.session_ids) > 1 for seance in this.session_id.seance_ids):
4637
raise osv.except_osv(_('Error'),
4638
_('You have selected a session with a shared seance'))
4640
#if not all(seance.state == 'opened' for seance in this.session_id.seance_ids):
4641
# raise osv.except_osv(_('Error'),
4642
# _('You have to open all seances in this session'))
4644
lengths = [len(group.seance_ids)
4645
for group in this.session_id.group_ids
4646
if group != this.group_id]
4648
if len(lengths) == 0:
4649
raise osv.except_osv(_('Error'),
4650
_('There is no group in this session !'))
4652
minimum, maximum = min(lengths), max(lengths)
4654
if minimum != maximum:
4655
raise osv.except_osv(_('Error'),
4656
_('The defined groups for this session does not have the same number of seances !'))
4658
group_id = this.session_id.group_ids[0]
4661
for group in this.session_id.group_ids:
4662
for seance in group.seance_ids:
4663
seance_sisters.setdefault((seance.date, seance.duration, seance.course_id, seance.kind,), {})[seance.id] = None
4667
if len(this.group_id.seance_ids) == 0:
4668
proxy_seance = self.pool.get('training.seance')
4670
for seance in group_id.seance_ids:
4672
'group_id' : this.group_id.id,
4673
'presence_form' : 'no',
4675
'participant_count_manual' : 0,
4676
'contact_ids' : [(6, 0, [])],
4677
'participant_ids' : [],
4680
'is_first_seance' : seance.is_first_seance,
4683
seance_ids.append( proxy_seance.copy(cr, uid, seance.id, values, context=context) )
4685
# If the there are some seances in this group
4686
seance_ids = [seance.id for seance in this.group_id.seance_ids]
4688
for seance in self.pool.get('training.seance').browse(cr, uid, seance_ids, context=context):
4689
key = (seance.date, seance.duration, seance.course_id, seance.kind,)
4690
if key in seance_sisters:
4691
for k, v in seance_sisters[key].items():
4692
seance_sisters[key][k] = seance.id
4694
seance_sisters[key][seance.id] = seance.id
4697
for key, values in seance_sisters.iteritems():
4698
for old_seance_id, new_seance_id in values.iteritems():
4699
final_mapping[old_seance_id] = new_seance_id
4701
for sl in this.subscription_line_ids:
4702
for part in sl.participation_ids:
4703
part.write({'seance_id' : final_mapping[part.seance_id.id]})
4705
return {'type' : 'ir.actions.act_window_close'}
4707
def default_get(self, cr, uid, fields, context=None):
4708
record_id = context and context.get('record_id', False) or False
4710
res = super(training_session_duplicate_wizard, self).default_get(cr, uid, fields, context=context)
4713
res['session_id'] = record_id
4717
training_session_duplicate_wizard()
4719
4277
class purchase_order(osv.osv):
4720
4278
_inherit = 'purchase.order'
4981
4539
training_config_invoice()
4983
class training_participation_reassign_wizard(osv.osv_memory):
4984
_name = 'training.participation.reassign.wizard'
4987
'participation_id' : fields.many2one('training.participation', 'Participation', required=True),
4988
'participation_seance_id' : fields.related('participation_id', 'seance_id', type='many2one', relation='training.seance', readonly=True, string='Seance'),
4989
'participation_seance_date' : fields.related('participation_id', 'seance_id', 'date', type='datetime', readonly=True, string='Date'),
4990
'participation_sl' : fields.related('participation_id', 'subscription_line_id', type='many2one', relation='training.subscription.line', readonly=True, string='Subscription Line'),
4991
'participation_session_id' : fields.related('participation_id', 'subscription_line_id', 'session_id', type='many2one', relation='training.session',
4994
'seance_id' : fields.many2one('training.seance', 'Seance',
4995
#domain="[('session_ids', 'in', [participation_session_id])]",
4999
def on_change_seance(self, cr, uid, ids, seance_id, context=None):
5002
'participation_id' : not seance_id and [] or [('seance_id', '=', seance_id)],
5008
def on_change_participation(self, cr, uid, ids, participation_id, context=None):
5009
if not participation_id:
5019
p = self.pool.get('training.participation').browse(cr, uid, participation_id, context=context)
5022
'participation_seance_id' : p.seance_id.id,
5023
'participation_seance_date' : p.seance_id.date,
5024
'participation_sl' : p.subscription_line_id.id,
5025
'participation_session_id' : p.subscription_line_id.session_id.id,
5028
'seance_id' : [('id', 'in', [seance.id for seance in p.subscription_line_id.session_id.seance_ids])],
5032
def close_cb(self, cr, uid, ids, context=None):
5033
return {'type' : 'ir.actions.act_window_close'}
5035
def apply_cb(self, cr, uid, ids, context=None):
5036
this = self.browse(cr, uid, ids[0], context=context)
5038
if this.participation_id.seance_id == this.seance_id:
5039
raise osv.except_osv(_('Warning'),
5040
_('You have selected the same seance'))
5042
this.participation_id.write({'seance_id' : this.seance_id.id})
5044
return {'type' : 'ir.actions.act_window_close'}
5046
training_participation_reassign_wizard()
5048
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: