Revision 2864e701 snf-astakos-app/astakos/quotaholder/callpoint.py

b/snf-astakos-app/astakos/quotaholder/callpoint.py
34 34
from astakos.quotaholder.exception import (
35 35
    QuotaholderError,
36 36
    CorruptedError, InvalidDataError,
37
    NoStockError, NoCapacityError,
37
    NoCapacityError,
38 38
    DuplicateError)
39 39

  
40 40
from astakos.quotaholder.commission import (
41
    Import, Export, Reclaim, Release, Operations)
41
    Import, Release, Operations)
42 42

  
43 43
from astakos.quotaholder.utils.newname import newname
44 44
from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE
......
56 56

  
57 57
    def _init_holding(self,
58 58
                      holder, resource, capacity,
59
                      imported_min, imported_max, stock_min, stock_max,
59
                      imported_min, imported_max,
60 60
                      flags):
61 61
        try:
62 62
            h = db_get_holding(holder=holder, resource=resource,
......
68 68
        h.flags = flags
69 69
        h.imported_min = imported_min
70 70
        h.imported_max = imported_max
71
        h.stock_min = stock_min
72
        h.stock_max = stock_max
73 71
        h.save()
74 72

  
75 73
    def init_holding(self, context=None, init_holding=[]):
......
78 76

  
79 77
        for idx, sfh in enumerate(init_holding):
80 78
            (holder, resource, capacity,
81
             imported_min, imported_max, stock_min, stock_max,
79
             imported_min, imported_max,
82 80
             flags) = sfh
83 81

  
84 82
            self._init_holding(holder, resource, capacity,
85 83
                               imported_min, imported_max,
86
                               stock_min, stock_max,
87 84
                               flags)
88 85
        if rejected:
89 86
            raise QuotaholderError(rejected)
......
94 91
        append = rejected.append
95 92

  
96 93
        for idx, tpl in enumerate(reset_holding):
97
            (holder, resource,
98
             imported_min, imported_max, stock_min, stock_max) = tpl
94
            (holder, source, resource,
95
             imported_min, imported_max) = tpl
99 96

  
100 97
            try:
101
                h = db_get_holding(holder=holder, resource=resource,
98
                h = db_get_holding(holder=holder,
99
                                   source=source,
100
                                   resource=resource,
102 101
                                   for_update=True)
103 102
                h.imported_min = imported_min
104 103
                h.imported_max = imported_max
105
                h.stock_min = stock_min
106
                h.stock_max = stock_max
107 104
                h.save()
108 105
            except Holding.DoesNotExist:
109 106
                append(idx)
......
113 110
            raise QuotaholderError(rejected)
114 111
        return rejected
115 112

  
116
    def _check_pending(self, holder, resource):
117
        cs = Commission.objects.filter(holder=holder)
118
        cs = [c for c in cs if c.provisions.filter(resource=resource)]
119
        as_target = [c.serial for c in cs]
120

  
121
        ps = Provision.objects.filter(holder=holder, resource=resource)
122
        as_source = [p.serial.serial for p in ps]
123

  
124
        return as_target + as_source
113
    def _check_pending(self, holding):
114
        ps = Provision.objects.filter(holding=holding)
115
        return ps.count()
125 116

  
126 117
    def release_holding(self, context=None, release_holding=[]):
127 118
        rejected = []
128 119
        append = rejected.append
129 120

  
130
        for idx, (holder, resource) in enumerate(release_holding):
121
        for idx, (holder, source, resource) in enumerate(release_holding):
131 122
            try:
132
                h = db_get_holding(holder=holder, resource=resource,
123
                h = db_get_holding(holder=holder,
124
                                   source=source,
125
                                   resource=resource,
133 126
                                   for_update=True)
134 127
            except Holding.DoesNotExist:
135 128
                append(idx)
136 129
                continue
137 130

  
138
            if self._check_pending(holder, resource):
131
            if self._check_pending(h):
139 132
                append(idx)
140 133
                continue
141 134

  
......
166 159
                reject(holder)
167 160
                continue
168 161

  
169
            append([(holder, h.resource,
170
                     h.imported_min, h.imported_max, h.stock_min, h.stock_max)
162
            append([(holder, h.source, h.resource,
163
                     h.imported_min, h.imported_max)
171 164
                    for h in holdings])
172 165

  
173 166
        return holdings_list, rejected
......
180 173
        hs = Holding.objects.filter(holder__in=holders)
181 174
        holdings = {}
182 175
        for h in hs:
183
            holdings[(h.holder, h.resource)] = h
176
            holdings[(h.holder, h.source, h.resource)] = h
184 177

  
185
        for holder, resource in get_quota:
178
        for holder, source, resource in get_quota:
186 179
            try:
187
                h = holdings[(holder, resource)]
180
                h = holdings[(holder, source, resource)]
188 181
            except:
189 182
                continue
190 183

  
191
            append((h.holder, h.resource, h.capacity,
184
            append((h.holder, h.source, h.resource, h.capacity,
192 185
                    h.imported_min, h.imported_max,
193
                    h.stock_min, h.stock_max,
194 186
                    h.flags))
195 187

  
196 188
        return quotas
......
201 193

  
202 194
        q_holdings = Q()
203 195
        holders = []
204
        for (holder, resource, _, _) in set_quota:
196
        for (holder, source, resource, _, _) in set_quota:
205 197
            holders.append(holder)
206 198

  
207 199
        hs = Holding.objects.filter(holder__in=holders).select_for_update()
208 200
        holdings = {}
209 201
        for h in hs:
210
            holdings[(h.holder, h.resource)] = h
202
            holdings[(h.holder, h.source, h.resource)] = h
211 203

  
212
        for (holder, resource,
204
        for (holder, source, resource,
213 205
             capacity,
214 206
             flags) in set_quota:
215 207

  
216 208
            try:
217
                h = holdings[(holder, resource)]
209
                h = holdings[(holder, source, resource)]
218 210
                h.flags = flags
219 211
            except KeyError:
220
                h = Holding(holder=holder, resource=resource,
212
                h = Holding(holder=holder,
213
                            source=source,
214
                            resource=resource,
221 215
                            flags=flags)
222 216

  
223 217
            h.capacity = capacity
224 218
            h.save()
225
            holdings[(holder, resource)] = h
219
            holdings[(holder, source, resource)] = h
226 220

  
227 221
        if rejected:
228 222
            raise QuotaholderError(rejected)
......
279 273
    def issue_commission(self,
280 274
                         context=None,
281 275
                         clientkey=None,
282
                         target=None,
283 276
                         name=None,
284 277
                         provisions=()):
285 278

  
279
        if name is None:
280
            name = ""
286 281
        create = Commission.objects.create
287
        commission = create(holder=target, clientkey=clientkey, name=name)
282
        commission = create(clientkey=clientkey, name=name)
288 283
        serial = commission.serial
289 284

  
290 285
        operations = Operations()
291 286

  
292 287
        try:
293 288
            checked = []
294
            for holder, resource, quantity in provisions:
289
            for holder, source, resource, quantity in provisions:
295 290

  
296
                if holder == target:
291
                if holder == source:
297 292
                    m = ("Cannot issue commission from a holder "
298 293
                         "to itself (%s)" % (holder,))
299 294
                    raise InvalidDataError(m)
......
304 299
                    raise DuplicateError(m)
305 300
                checked.append(ent_res)
306 301

  
307
                # Source
308
                try:
309
                    h = (db_get_holding(holder=holder, resource=resource,
310
                                        for_update=True)
311
                         if holder is not None
312
                         else None)
313
                except Holding.DoesNotExist:
314
                    m = ("%s has no stock of %s." % (holder, resource))
315
                    raise NoStockError(m,
316
                                       holder=holder,
317
                                       resource=resource,
318
                                       requested=quantity,
319
                                       current=0,
320
                                       limit=0)
321

  
322 302
                # Target
323 303
                try:
324
                    th = db_get_holding(holder=target, resource=resource,
304
                    th = db_get_holding(holder=holder,
305
                                        resource=resource,
306
                                        source=source,
325 307
                                        for_update=True)
326 308
                except Holding.DoesNotExist:
327 309
                    m = ("There is no capacity "
328
                         "to allocate into in %s.%s" % (target, resource))
310
                         "to allocate into in %s.%s" % (holder, resource))
329 311
                    raise NoCapacityError(m,
330 312
                                          holder=holder,
331 313
                                          resource=resource,
......
334 316
                                          limit=0)
335 317

  
336 318
                if quantity >= 0:
337
                    if h is not None:
338
                        operations.prepare(Export, h, quantity)
339 319
                    operations.prepare(Import, th, quantity)
340 320

  
341 321
                else: # release
342 322
                    abs_quantity = -quantity
343

  
344
                    if h is not None:
345
                        operations.prepare(Reclaim, h, abs_quantity)
346 323
                    operations.prepare(Release, th, abs_quantity)
347 324

  
348 325
                Provision.objects.create(serial=commission,
349
                                         holder=holder,
350
                                         resource=resource,
326
                                         holding=th,
351 327
                                         quantity=quantity)
352 328

  
353 329
        except QuotaholderError:
......
357 333
        return serial
358 334

  
359 335
    def _log_provision(self,
360
                       commission, s_holding, t_holding,
361
                       provision, log_time, reason):
362

  
363
        if s_holding is not None:
364
            s_holder = s_holding.holder
365
            s_capacity = s_holding.capacity
366
            s_imported_min = s_holding.imported_min
367
            s_imported_max = s_holding.imported_max
368
            s_stock_min = s_holding.stock_min
369
            s_stock_max = s_holding.stock_max
370
        else:
371
            s_holder = None
372
            s_capacity = None
373
            s_imported_min = None
374
            s_imported_max = None
375
            s_stock_min = None
376
            s_stock_max = None
336
                       commission, provision, log_time, reason):
337

  
338
        holding = provision.holding
377 339

  
378 340
        kwargs = {
379 341
            'serial':              commission.serial,
380 342
            'name':                commission.name,
381
            'source':              s_holder,
382
            'target':              t_holding.holder,
383
            'resource':            provision.resource,
384
            'source_capacity':     s_capacity,
385
            'source_imported_min': s_imported_min,
386
            'source_imported_max': s_imported_max,
387
            'source_stock_min':    s_stock_min,
388
            'source_stock_max':    s_stock_max,
389
            'target_capacity':     t_holding.capacity,
390
            'target_imported_min': t_holding.imported_min,
391
            'target_imported_max': t_holding.imported_max,
392
            'target_stock_min':    t_holding.stock_min,
393
            'target_stock_max':    t_holding.stock_max,
343
            'holder':              holding.holder,
344
            'source':              holding.source,
345
            'resource':            holding.resource,
346
            'capacity':            holding.capacity,
347
            'imported_min':        holding.imported_min,
348
            'imported_max':        holding.imported_max,
394 349
            'delta_quantity':      provision.quantity,
395 350
            'issue_time':          commission.issue_time,
396 351
            'log_time':            log_time,
......
411 366
            except Commission.DoesNotExist:
412 367
                return
413 368

  
414
            t = c.holder
415

  
416 369
            operations = Operations()
417 370

  
418 371
            provisions = db_filter_provision(serial=serial, for_update=True)
419 372
            for pv in provisions:
420 373
                try:
421
                    h = (db_get_holding(holder=pv.holder,
422
                                        resource=pv.resource, for_update=True)
423
                         if pv.holder is not None
424
                         else None)
425
                    th = db_get_holding(holder=t, resource=pv.resource,
374
                    th = db_get_holding(id=pv.holding_id,
426 375
                                        for_update=True)
427 376
                except Holding.DoesNotExist:
428 377
                    m = "Corrupted provision"
......
431 380
                quantity = pv.quantity
432 381

  
433 382
                if quantity >= 0:
434
                    if h is not None:
435
                        operations.finalize(Export, h, quantity)
436 383
                    operations.finalize(Import, th, quantity)
437 384
                else: # release
438 385
                    abs_quantity = -quantity
439

  
440
                    if h is not None:
441
                        operations.finalize(Reclaim, h, abs_quantity)
442 386
                    operations.finalize(Release, th, abs_quantity)
443 387

  
444 388
                reason = 'ACCEPT:' + reason[-121:]
445
                self._log_provision(c, h, th, pv, log_time, reason)
389
                self._log_provision(c, pv, log_time, reason)
446 390
                pv.delete()
447 391
            c.delete()
448 392

  
......
460 404
            except Commission.DoesNotExist:
461 405
                return
462 406

  
463
            t = c.holder
464

  
465 407
            operations = Operations()
466 408

  
467 409
            provisions = db_filter_provision(serial=serial, for_update=True)
468 410
            for pv in provisions:
469 411
                try:
470
                    h = (db_get_holding(holder=pv.holder,
471
                                        resource=pv.resource, for_update=True)
472
                         if pv.holder is not None
473
                         else None)
474
                    th = db_get_holding(holder=t, resource=pv.resource,
412
                    th = db_get_holding(id=pv.holding_id,
475 413
                                        for_update=True)
476 414
                except Holding.DoesNotExist:
477 415
                    m = "Corrupted provision"
......
480 418
                quantity = pv.quantity
481 419

  
482 420
                if quantity >= 0:
483
                    if h is not None:
484
                        operations.undo(Export, h, quantity)
485 421
                    operations.undo(Import, th, quantity)
486 422
                else: # release
487 423
                    abs_quantity = -quantity
488

  
489
                    if h is not None:
490
                        operations.undo(Reclaim, h, abs_quantity)
491 424
                    operations.undo(Release, th, abs_quantity)
492 425

  
493 426
                reason = 'REJECT:' + reason[-121:]
494
                self._log_provision(c, h, th, pv, log_time, reason)
427
                self._log_provision(c, pv, log_time, reason)
495 428
                pv.delete()
496 429
            c.delete()
497 430

  

Also available in: Unified diff