~openerp-commiter/openobject-addons/extra-6.0

« back to all changes in this revision

Viewing changes to training/training.py

  • Committer: Albert Cervera i Areny
  • Date: 2011-06-14 09:51:35 UTC
  • mfrom: (5345.1.165 openobject-addons)
  • Revision ID: albert@nan-tic.com-20110614095135-1x3p6tmil5lxkl9b
Merge and add nan_remove_default_filters

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#
23
23
############################################################################################
24
24
 
 
25
from osv import osv, fields
 
26
from tools.translate import _
 
27
 
25
28
from cStringIO import StringIO
26
 
from osv import osv, fields
27
 
import decimal_precision as dp
28
29
from tools import config
29
 
from tools.translate import _
30
30
from zipfile import PyZipFile, ZIP_DEFLATED
 
31
 
 
32
import decimal_precision as dp
31
33
import base64
32
34
import mx.DateTime
33
35
import netsvc
652
654
 
653
655
training_offer_format()
654
656
 
655
 
class training_offer_purchase_line_update_wizard(osv.osv_memory):
656
 
    _name = 'training.offer.purchase.line.update.wizard'
657
 
    _columns = {
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')]),
662
 
    }
663
 
 
664
 
    _defaults = {
665
 
        'state': lambda *a: 'confirm',
666
 
    }
667
 
 
668
 
    def action_cancel(self, cr, uid, ids, context=None):
669
 
        return {'type': 'ir.actions.act_window_close' }
670
 
 
671
 
    def action_close(self, cr, uid, ids, context=None):
672
 
        return {'type': 'ir.actions.act_window_close' }
673
 
 
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)
678
 
        if val:
679
 
            val['state'] = 'update'
680
 
        else:
681
 
            val = { 'name': _('FAILED')}
682
 
        return self.write(cr, uid, ids, val, context=context)
683
 
 
684
 
training_offer_purchase_line_update_wizard()
685
657
 
686
658
class training_offer_purchase_line_log(osv.osv):
687
659
    _name = 'training.offer.purchase.line.log'
782
754
    _name = 'training.offer'
783
755
    _description = 'Offer'
784
756
 
785
 
    def on_change_course_ids(self, cr, uid, ids, course_ids, context=None):
786
 
        values = {
787
 
            'type_id' : 0,
788
 
            'product_line_id' : 0,
789
 
        }
790
 
 
791
 
        if len(course_ids) == 1:
792
 
            course = self.pool.get('training.course').browse(cr, uid, course_ids[0][2]['course_id'])
793
 
 
794
 
            values.update({
795
 
                'name' : course.name,
796
 
                'type_id' : course.course_type_id.id,
797
 
                'product_line_id' : course.category_id.id,
798
 
            })
799
 
 
800
 
        # Creer un bouton 'draft' qui rebalance en draft quand une offre est deja deprecated
801
 
        return {'value' : values}
802
 
 
803
757
    def _is_standalone_compute(self, cr, uid, ids, fieldnames, args, context=None):
804
758
        res = dict.fromkeys(ids, 0)
805
759
        for offer in self.browse(cr, uid, ids, context=context):
1162
1116
 
1163
1117
training_catalog()
1164
1118
 
1165
 
def get_zip_from_directory(directory, b64enc=True):
1166
 
    RE_exclude = re.compile('(?:^\..+\.swp$)|(?:\.py[oc]$)|(?:\.bak$)|(?:\.~.~$)', re.I)
1167
 
 
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))
1175
 
 
1176
 
    archname = StringIO()
1177
 
    archive = PyZipFile(archname, "w", ZIP_DEFLATED)
1178
 
    archive.writepy(directory)
1179
 
    _zippy(archive, directory)
1180
 
    archive.close()
1181
 
    val = archname.getvalue()
1182
 
    archname.close()
1183
 
 
1184
 
    if b64enc:
1185
 
        val = base64.encodestring(val)
1186
 
 
1187
 
    return val
1188
 
 
1189
 
class training_seance_generate_pdf_wizard(osv.osv_memory):
1190
 
    _name = 'training.seance.generate.zip.wizard'
1191
 
 
1192
 
    _columns = {
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),
1202
 
    }
1203
 
 
1204
 
    _defaults = {
1205
 
        'presence_list_report' : lambda *a: 0,
1206
 
        'remuneration_form_report' : lambda *a: 0,
1207
 
        'state' : lambda *a: 'selection',
1208
 
    }
1209
 
 
1210
 
    def action_close(self, cr, uid, ids, context=None):
1211
 
        return { 'type' : 'ir.actions.act_window.close' }
1212
 
 
1213
 
    def action_generate_zip(self, cr, uid, ids, context=None):
1214
 
        try:
1215
 
            import tempfile
1216
 
            parent_directory = tempfile.mkdtemp(prefix='openerp_', suffix='_reports')
1217
 
            directory = os.path.join(parent_directory, 'Reports')
1218
 
            os.mkdir(directory)
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')
1222
 
            fp.write(result)
1223
 
            fp.close()
1224
 
 
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)
1229
 
 
1230
 
            values = {
1231
 
                'state' : 'result',
1232
 
                'zip_file' : result,
1233
 
                'zip_file_name' : 'Seance_Reports_%s_%06d.zip' % (date, seance.id),
1234
 
            }
1235
 
        finally:
1236
 
            import shutil
1237
 
            shutil.rmtree(parent_directory)
1238
 
        return self.write(cr, uid, ids, values, context=context)
1239
 
 
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)
1243
 
        return pdf
1244
 
 
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')
1255
 
                fp.write(res)
1256
 
                fp.close()
1257
 
 
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) )
1263
 
 
1264
 
                    if not contact.request_id.purchase_order_id:
1265
 
                        raise osv.except_osv(_('Error'),
1266
 
                                             _('There is no Purchase Order for a request'))
1267
 
 
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'))
1271
 
 
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')
1276
 
                    fp.write(res)
1277
 
                    fp.close()
1278
 
 
1279
 
training_seance_generate_pdf_wizard()
1280
1119
 
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:
1581
1420
                    return False
 
1421
        return True
1582
1422
 
 
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:
 
1427
                    return False
1583
1428
        return True
1584
1429
 
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']),
1589
1435
    ]
1590
1436
 
1591
1437
    def _find_catalog_id(self, cr, uid, context=None):
2063
1909
 
2064
1910
training_session()
2065
1911
 
2066
 
class training_subscription_mass_wizard(osv.osv_memory):
2067
 
    _name = 'training.subscription.mass.wizard'
2068
 
    _description = 'Mass Subscription Wizard'
2069
 
 
2070
 
    def action_cancel(self, cr, uid, ids, context=None):
2071
 
        return {'type':'ir.actions.act_window_close'}
2072
 
 
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
2076
 
 
2077
 
        this = self.browse(cr, uid, ids)[0]
2078
 
 
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')
2082
 
 
2083
 
        subscriptions = {}
2084
 
 
2085
 
        if record_id:
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)
2089
 
 
2090
 
            return {
2091
 
                'type' : 'ir.actions.act_window_close',
2092
 
            }
2093
 
 
2094
 
        for job in this.job_ids:
2095
 
            # if the job hasn't a partner, we put this subscription in waiting mode
2096
 
            if not job.name:
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)
2099
 
 
2100
 
            else:
2101
 
                for subscription_mass_line in this.session_ids:
2102
 
                    subscriptions.setdefault(job.name.id, []).append((job, subscription_mass_line,))
2103
 
 
2104
 
        subscription_ids = []
2105
 
 
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']
2109
 
            values.update({
2110
 
                'partner_id' : partner_id,
2111
 
            })
2112
 
 
2113
 
            subscription_id = subscription_proxy.create(cr, uid, values, context=context)
2114
 
 
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)
2117
 
 
2118
 
            subscription_ids.append(subscription_id)
2119
 
            
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')
2125
 
 
2126
 
        return act_win
2127
 
 
2128
 
    _columns = {
2129
 
        'partner_id' : fields.many2one('res.partner', 'Partner'),
2130
 
        'job_ids' : fields.many2many('res.partner.job',
2131
 
                                     'tms_contact_job_rel',
2132
 
                                     'ms_id',
2133
 
                                     'job_id',
2134
 
                                     'Contacts',
2135
 
                                    ),
2136
 
        'session_ids' : fields.one2many('training.subscription.mass.line', 'wizard_id', 'Sessions'),
2137
 
    }
2138
 
 
2139
 
    def default_get(self, cr, uid, fields, context=None):
2140
 
        record_id = context and context.get('record_id', False) or False
2141
 
 
2142
 
        res = super(training_subscription_mass_wizard, self).default_get(cr, uid, fields, context=context)
2143
 
 
2144
 
        if record_id:
2145
 
            partner_id = self.pool.get('training.subscription').browse(cr, uid, record_id, context=context).partner_id.id
2146
 
            res['partner_id'] = partner_id
2147
 
 
2148
 
        return res
2149
 
 
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
2152
 
 
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)
2154
 
        if record_id:
2155
 
            if 'fields' in res and 'partner_id' in res['fields']:
2156
 
                res['fields']['partner_id']['readonly'] = True
2157
 
 
2158
 
        return res
2159
 
 
2160
 
training_subscription_mass_wizard()
2161
 
 
2162
 
class mass_subscription_line(osv.osv_memory):
2163
 
    _name = 'training.subscription.mass.line'
2164
 
 
2165
 
    _columns = {
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',
2171
 
                                type='selection',
2172
 
                                selection=training_offer_kind_compute,
2173
 
                                string='Kind',
2174
 
                                readonly=True),
2175
 
    }
2176
 
 
2177
 
    def on_change_allow_closed_session(self, cr, uid, ids, new_allow, context=None):
2178
 
        if new_allow:
2179
 
            return {
2180
 
                'domain': {'session_id': []}
2181
 
            }
2182
 
        else:
2183
 
            return {
2184
 
                'domain': {'session_id': [('state', 'in', ('opened','opened_confirmed', 'closed_confirmed', 'inprogress'))]}
2185
 
            }
2186
 
 
2187
 
 
2188
 
    def on_change_session(self, cr, uid, ids, context=None):
2189
 
        return {}
2190
 
 
2191
 
mass_subscription_line()
2192
1912
 
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),
2269
1989
                                      }
2270
1990
                                      ),
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',
2272
1992
                                            store={
2273
1993
                                                'training.subscription.line': (_store_get_sublines, None, 11),
2274
1994
                                            }
2275
1995
                                            ),
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',
2277
1997
                                            store={
2278
1998
                                                'training.subscription.line': (_store_get_sublines, None, 11),
2279
1999
                                            }
3025
2745
                                                  'training.subscription' : (lambda self, cr, uid, ids, context=None: ids, None, 10),
3026
2746
                                              },
3027
2747
                                              size=64),
3028
 
        'is_from_web': fields.boolean('Is from Web?', help='Is this subscription come from an online order.', readonly=True),
 
2748
        'comment': fields.text('Additional Information'),
3029
2749
    }
3030
2750
 
3031
2751
    def create(self, cr, uid, vals, context):
3282
3002
        'was_present': fields.function(_was_present_compute, method=True, type='boolean', string='Was Present'),
3283
3003
    }
3284
3004
 
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)
3287
3009
 
3288
3010
    def unlink(self, cr, uid, vals, context):
3289
3011
        subscription_lines = self.read(cr, uid, vals, ['state'])
3297
3019
 
3298
3020
    _defaults = {
3299
3021
        'state' : lambda *a: 'draft',
3300
 
        'name' : _default_name,
3301
 
        #lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'training.subscription.line'),
 
3022
        'name' : lambda *args: '/',
3302
3023
        'has_certificate' : lambda *a: 0,
3303
3024
    }
3304
3025
 
4523
4244
 
4524
4245
training_course_pending()
4525
4246
 
4526
 
class training_course_pending_wizard(osv.osv_memory):
4527
 
    _name = 'training.course.pending.wizard'
4528
 
 
4529
 
    _columns = {
4530
 
        'course_id' : fields.many2one('training.course', 'Course'),
4531
 
        'type' : fields.selection(training_course_pending_reason_compute,
4532
 
                                    'Type',
4533
 
                                    size=32,
4534
 
                                    required=True),
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')],
4540
 
                                   'State')
4541
 
    }
4542
 
 
4543
 
    _defaults = {
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)
4547
 
    }
4548
 
 
4549
 
    def action_cancel(self, cr, uid, ids, context=None):
4550
 
        return {'type' : 'ir.actions.act_window_close'}
4551
 
 
4552
 
    def action_apply(self, cr, uid, ids, context=None):
4553
 
        course_id = context and context.get('active_id', False) or False
4554
 
 
4555
 
        if not course_id:
4556
 
            return False
4557
 
 
4558
 
        this = self.browse(cr, uid, ids)[0]
4559
 
 
4560
 
        workflow = netsvc.LocalService('workflow')
4561
 
        workflow.trg_validate(uid, 'training.course', course_id, 'signal_pending', cr)
4562
 
 
4563
 
        values = {
4564
 
            'course_id' : course_id,
4565
 
            'type' : this.type,
4566
 
            'date' : this.date,
4567
 
            'reason' : this.reason,
4568
 
            'job_id' : this.job_id and this.job_id.id,
4569
 
        }
4570
 
 
4571
 
        self.pool.get('training.course.pending').create(cr, uid, values, context=context)
4572
 
 
4573
 
        return {'res_id' : course_id}
4574
 
 
4575
 
training_course_pending_wizard()
4576
 
 
4577
4247
 
4578
4248
class training_contact_course(osv.osv):
4579
4249
    _name = 'training.contact.course'
4603
4273
 
4604
4274
res_partner_contact()
4605
4275
 
4606
 
class training_session_duplicate_wizard(osv.osv_memory):
4607
 
    _name = 'training.session.duplicate.wizard'
4608
 
 
4609
 
    _columns = {
4610
 
        'session_id': fields.many2one('training.session', 'Session',
4611
 
                                      required=True,
4612
 
                                      readonly=True,
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',
4618
 
                                                   'wizard_id',
4619
 
                                                   'participation_id',
4620
 
                                                   'Participations',
4621
 
                                                   domain="[('session_id', '=', session_id),('state', '=', 'confirmed')]"),
4622
 
    }
4623
 
 
4624
 
    def action_cancel(self, cr, uid, ids, context=None):
4625
 
        return {'type' : 'ir.actions.act_window_close'}
4626
 
 
4627
 
    def action_apply(self, cr, uid, ids, context=None):
4628
 
        this = self.browse(cr, uid, ids[0], context=context)
4629
 
 
4630
 
        if len(this.subscription_line_ids) == 0:
4631
 
            raise osv.except_osv(_('Error'),
4632
 
                                 _('You have not selected a participant of this session'))
4633
 
 
4634
 
        seances = []
4635
 
 
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'))
4639
 
 
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'))
4643
 
 
4644
 
        lengths = [len(group.seance_ids)
4645
 
                   for group in this.session_id.group_ids
4646
 
                   if group != this.group_id]
4647
 
 
4648
 
        if len(lengths) == 0:
4649
 
            raise osv.except_osv(_('Error'),
4650
 
                                 _('There is no group in this session !'))
4651
 
 
4652
 
        minimum, maximum = min(lengths), max(lengths)
4653
 
 
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 !'))
4657
 
 
4658
 
        group_id = this.session_id.group_ids[0]
4659
 
 
4660
 
        seance_sisters = {}
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
4664
 
 
4665
 
        seance_ids = []
4666
 
 
4667
 
        if len(this.group_id.seance_ids) == 0:
4668
 
            proxy_seance = self.pool.get('training.seance')
4669
 
 
4670
 
            for seance in group_id.seance_ids:
4671
 
                values = {
4672
 
                    'group_id' : this.group_id.id,
4673
 
                    'presence_form' : 'no',
4674
 
                    'manual' : 0,
4675
 
                    'participant_count_manual' : 0,
4676
 
                    'contact_ids' : [(6, 0, [])],
4677
 
                    'participant_ids' : [],
4678
 
                    'duplicata' : 1,
4679
 
                    'duplicated' : 1,
4680
 
                    'is_first_seance' : seance.is_first_seance,
4681
 
                }
4682
 
 
4683
 
                seance_ids.append( proxy_seance.copy(cr, uid, seance.id, values, context=context) )
4684
 
        else:
4685
 
            # If the there are some seances in this group
4686
 
            seance_ids = [seance.id for seance in this.group_id.seance_ids]
4687
 
 
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
4693
 
            else:
4694
 
                seance_sisters[key][seance.id] = seance.id
4695
 
 
4696
 
        final_mapping = {}
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
4700
 
 
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]})
4704
 
 
4705
 
        return {'type' : 'ir.actions.act_window_close'}
4706
 
 
4707
 
    def default_get(self, cr, uid, fields, context=None):
4708
 
        record_id = context and context.get('record_id', False) or False
4709
 
 
4710
 
        res = super(training_session_duplicate_wizard, self).default_get(cr, uid, fields, context=context)
4711
 
 
4712
 
        if record_id:
4713
 
            res['session_id'] = record_id
4714
 
 
4715
 
        return res
4716
 
 
4717
 
training_session_duplicate_wizard()
4718
4276
 
4719
4277
class purchase_order(osv.osv):
4720
4278
    _inherit = 'purchase.order'
4979
4537
    ]
4980
4538
 
4981
4539
training_config_invoice()
4982
 
 
4983
 
class training_participation_reassign_wizard(osv.osv_memory):
4984
 
    _name = 'training.participation.reassign.wizard'
4985
 
 
4986
 
    _columns = {
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',
4992
 
                                                    readonly=True,
4993
 
                                                    string='Session'),
4994
 
        'seance_id' : fields.many2one('training.seance', 'Seance',
4995
 
                                      #domain="[('session_ids', 'in', [participation_session_id])]",
4996
 
                                      required=True),
4997
 
    }
4998
 
 
4999
 
    def on_change_seance(self, cr, uid, ids, seance_id, context=None):
5000
 
        values = {
5001
 
            'domain' : {
5002
 
                'participation_id' : not seance_id and [] or [('seance_id', '=', seance_id)],
5003
 
            }
5004
 
        }
5005
 
 
5006
 
        return values
5007
 
 
5008
 
    def on_change_participation(self, cr, uid, ids, participation_id, context=None):
5009
 
        if not participation_id:
5010
 
            return {
5011
 
                'value' : {
5012
 
                    'seance_id' : 0,
5013
 
                },
5014
 
                'domain' : {
5015
 
                    'seance_id' : [],
5016
 
                },
5017
 
            }
5018
 
 
5019
 
        p = self.pool.get('training.participation').browse(cr, uid, participation_id, context=context)
5020
 
        return {
5021
 
            'value' : {
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,
5026
 
            },
5027
 
            'domain' : {
5028
 
                'seance_id' : [('id', 'in', [seance.id for seance in p.subscription_line_id.session_id.seance_ids])],
5029
 
            }
5030
 
        }
5031
 
 
5032
 
    def close_cb(self, cr, uid, ids, context=None):
5033
 
        return {'type' : 'ir.actions.act_window_close'}
5034
 
 
5035
 
    def apply_cb(self, cr, uid, ids, context=None):
5036
 
        this = self.browse(cr, uid, ids[0], context=context)
5037
 
 
5038
 
        if this.participation_id.seance_id == this.seance_id:
5039
 
            raise osv.except_osv(_('Warning'),
5040
 
                                 _('You have selected the same seance'))
5041
 
 
5042
 
        this.participation_id.write({'seance_id' : this.seance_id.id})
5043
 
 
5044
 
        return {'type' : 'ir.actions.act_window_close'}
5045
 
 
5046
 
training_participation_reassign_wizard()
5047
 
 
5048
 
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: