Revision 04dcc30e

b/snf-astakos-app/astakos/quotaholder/callpoint.py
306 306

  
307 307
                # Source
308 308
                try:
309
                    h = db_get_holding(holder=holder, resource=resource,
310
                                       for_update=True)
309
                    h = (db_get_holding(holder=holder, resource=resource,
310
                                        for_update=True)
311
                         if holder is not None
312
                         else None)
311 313
                except Holding.DoesNotExist:
312 314
                    m = ("%s has no stock of %s." % (holder, resource))
313 315
                    raise NoStockError(m,
......
332 334
                                          limit=0)
333 335

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

  
338 341
                else: # release
339 342
                    abs_quantity = -quantity
340 343

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

  
344 348
                Provision.objects.create(serial=commission,
......
356 360
                       commission, s_holding, t_holding,
357 361
                       provision, log_time, reason):
358 362

  
359
        s_holder = s_holding.holder
360
        t_holder = t_holding.holder
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
361 377

  
362 378
        kwargs = {
363 379
            'serial':              commission.serial,
364 380
            'name':                commission.name,
365 381
            'source':              s_holder,
366
            'target':              t_holder,
382
            'target':              t_holding.holder,
367 383
            'resource':            provision.resource,
368
            'source_capacity':     s_holding.capacity,
369
            'source_imported_min': s_holding.imported_min,
370
            'source_imported_max': s_holding.imported_max,
371
            'source_stock_min':    s_holding.stock_min,
372
            'source_stock_max':    s_holding.stock_max,
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,
373 389
            'target_capacity':     t_holding.capacity,
374 390
            'target_imported_min': t_holding.imported_min,
375 391
            'target_imported_max': t_holding.imported_max,
......
402 418
            provisions = db_filter_provision(serial=serial, for_update=True)
403 419
            for pv in provisions:
404 420
                try:
405
                    h = db_get_holding(holder=pv.holder,
406
                                       resource=pv.resource, for_update=True)
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)
407 425
                    th = db_get_holding(holder=t, resource=pv.resource,
408 426
                                        for_update=True)
409 427
                except Holding.DoesNotExist:
......
413 431
                quantity = pv.quantity
414 432

  
415 433
                if quantity >= 0:
416
                    operations.finalize(Export, h, quantity)
434
                    if h is not None:
435
                        operations.finalize(Export, h, quantity)
417 436
                    operations.finalize(Import, th, quantity)
418 437
                else: # release
419 438
                    abs_quantity = -quantity
420 439

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

  
424 444
                reason = 'ACCEPT:' + reason[-121:]
......
447 467
            provisions = db_filter_provision(serial=serial, for_update=True)
448 468
            for pv in provisions:
449 469
                try:
450
                    h = db_get_holding(holder=pv.holder,
451
                                       resource=pv.resource, for_update=True)
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)
452 474
                    th = db_get_holding(holder=t, resource=pv.resource,
453 475
                                        for_update=True)
454 476
                except Holding.DoesNotExist:
......
458 480
                quantity = pv.quantity
459 481

  
460 482
                if quantity >= 0:
461
                    operations.undo(Export, h, quantity)
483
                    if h is not None:
484
                        operations.undo(Export, h, quantity)
462 485
                    operations.undo(Import, th, quantity)
463 486
                else: # release
464 487
                    abs_quantity = -quantity
465 488

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

  
469 493
                reason = 'REJECT:' + reason[-121:]
b/snf-astakos-app/astakos/quotaholder/models.py
80 80
                                to_field='serial',
81 81
                                related_name='provisions'   )
82 82

  
83
    holder      =   CharField(max_length=4096, db_index=True)
83
    holder      =   CharField(max_length=4096, db_index=True, null=True)
84 84
    resource    =   CharField(max_length=4096, null=False)
85 85
    quantity    =   intDecimalField()
86 86

  
......
89 89
class ProvisionLog(Model):
90 90

  
91 91
    serial              =   BigIntegerField()
92
    source              =   CharField(max_length=4096)
92
    source              =   CharField(max_length=4096, null=True)
93 93
    target              =   CharField(max_length=4096)
94 94
    name                =   CharField(max_length=4096)
95 95
    issue_time          =   CharField(max_length=4096)
96 96
    log_time            =   CharField(max_length=4096)
97 97
    resource            =   CharField(max_length=4096)
98
    source_capacity     =   intDecimalField()
99
    source_imported_min =   intDecimalField()
100
    source_imported_max =   intDecimalField()
101
    source_stock_min    =   intDecimalField()
102
    source_stock_max    =   intDecimalField()
98
    source_capacity     =   intDecimalField(null=True)
99
    source_imported_min =   intDecimalField(null=True)
100
    source_imported_max =   intDecimalField(null=True)
101
    source_stock_min    =   intDecimalField(null=True)
102
    source_stock_max    =   intDecimalField(null=True)
103 103
    target_capacity     =   intDecimalField()
104 104
    target_imported_min =   intDecimalField()
105 105
    target_imported_max =   intDecimalField()
b/snf-astakos-app/astakos/quotaholder/test/simpletests.py
178 178
                             + DEFAULT_HOLDING + (0,)])
179 179

  
180 180
    @transaction.commit_on_success
181
    def initialize_holding(self, holder, resource, quantity):
182
        s = self.qh.issue_commission(clientkey=self.client, target=holder,
183
                                     name='initialize',
184
                                     provisions=[(None, resource, quantity)])
185
        self.qh.accept_commission(clientkey=self.client, serials=[s])
186

  
187
    @transaction.commit_on_success
188
    def issue_commission(self, target, provisions):
189
        return self.qh.issue_commission(clientkey=self.client, target=target,
190
                                        name='something',
191
                                        provisions=provisions)
192

  
193
    @transaction.commit_on_success
181 194
    def test_0090_commissions(self):
182 195
        e0 = self.rand_holder()
183 196
        e1 = self.rand_holder()
......
185 198
        c0, = self.new_quota(e0, resource)
186 199
        c1, = self.new_quota(e1, resource)
187 200

  
188
        @transaction.commit_on_success
189
        def f():
190
            self.qh.reset_holding(
191
                reset_holding=[(e1, resource, c1, c1, c1, c1)])
192

  
193
            most = min(c0, c1)
194
            if most < 0:
195
                raise AssertionError("%s <= 0" % most)
201
        self.initialize_holding(e1, resource, c1)
196 202

  
197
            return self.qh.issue_commission(clientkey=self.client, target=e0,
198
                                            name='something',
199
                                            provisions=[(e1, resource, most)])
203
        most = min(c0, c1)
204
        if most < 0:
205
            raise AssertionError("%s <= 0" % most)
200 206

  
201
        r = f()
202

  
203
        self.assertEqual(r, 1)
204

  
205
        @transaction.commit_on_success
206
        def f():
207
            self.qh.issue_commission(clientkey=self.client, target=e0,
208
                                     name='something',
209
                                     provisions=[(e1, resource, 1)])
207
        s1 = self.issue_commission(target=e0,
208
                                   provisions=[(e1, resource, most)])
209
        self.assertGreater(s1, 0)
210 210

  
211 211
        with self.assertRaises(CommissionValueException):
212
            f()
212
            self.issue_commission(target=e0,
213
                                  provisions=[(e1, resource, 1)])
213 214

  
214 215
        r = self.qh.get_pending_commissions(clientkey=self.client)
215
        self.assertEqual(list(r), [1])
216
        self.assertEqual(list(r), [s1])
216 217
        r = self.qh.resolve_pending_commissions(clientkey=self.client,
217
                                                max_serial=1, accept_set=[1])
218
                                                max_serial=s1, accept_set=[s1])
218 219
        r = self.qh.get_pending_commissions(clientkey=self.client)
219 220
        self.assertEqual(list(r), [])
220 221

  
......
230 231
        self.new_quota(et1, resource, (15,))
231 232
        self.new_quota(et2, resource, (15,))
232 233

  
233
        self.qh.reset_holding(
234
            reset_holding=[(es1, resource, 10, 10, 10, 10),
235
                           (es2, resource, 10, 10, 10, 10)])
234
        self.initialize_holding(es1, resource, 10)
235
        self.initialize_holding(es2, resource, 10)
236 236

  
237 237
        with self.assertRaises(NoStockError) as cm:
238 238
            self.qh.issue_commission(clientkey=self.client, target=et1,
......
280 280
                                     (e0, resource, 10, 0),
281 281
                                     (e1, resource, 10, 0)])
282 282

  
283
        self.qh.reset_holding(
284
            reset_holding=[(sys, resource, 10, 10, 10, 10)])
283
        self.initialize_holding(sys, resource, 10)
285 284

  
286 285
        s0 = self.qh.issue_commission(clientkey=self.client, target=e0,
287 286
                                      name='a commission',
......
313 312
        e = self.rand_holder()
314 313
        resource = self.rand_resource()
315 314
        limits = self.new_quota(e, resource, (2,))
316
        self.qh.reset_holding(
317
            reset_holding=[(e, resource, 1, 1, 1, 1)])
315

  
316
        self.initialize_holding(e, resource, 1)
318 317

  
319 318
        with self.assertRaises(QuotaholderError) as cm:
320 319
            self.qh.release_holding(release_holding=[(e, resource)])
......
337 336
        es = self.rand_holder()
338 337
        limits_s = self.new_quota(es, resource, (3,))
339 338

  
340
        self.qh.reset_holding(
341
            reset_holding=[(es, resource, 3, 3, 3, 3)])
339
        self.initialize_holding(es, resource, 3)
342 340

  
343 341
        e = self.rand_holder()
344 342
        limits = self.new_quota(e, resource, (2,))
......
385 383
        target = "test_015_release_nocapacity_target"
386 384
        flags = 0
387 385

  
388
        qh.init_holding(init_holding=[(source, resource, 6, 6, 6, 6, 6, 0)])
386
        qh.set_quota(set_quota=[(source, resource, 6, 0)])
387
        self.initialize_holding(source, resource, 6)
388

  
389 389
        qh.set_quota(set_quota=[(target, resource, 5, 0)])
390 390

  
391 391
        serial = qh.issue_commission(clientkey=self.client, target=target,

Also available in: Unified diff