Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / quotaholder / callpoint.py @ 8288906d

History | View | Annotate | Download (29.6 kB)

1 1d734153 Giorgos Korfiatis
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 3e5941c1 Giorgos Korfiatis
#
3 3e5941c1 Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 3e5941c1 Giorgos Korfiatis
# without modification, are permitted provided that the following
5 3e5941c1 Giorgos Korfiatis
# conditions are met:
6 3e5941c1 Giorgos Korfiatis
#
7 3e5941c1 Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 3e5941c1 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 3e5941c1 Giorgos Korfiatis
#      disclaimer.
10 3e5941c1 Giorgos Korfiatis
#
11 3e5941c1 Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 3e5941c1 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 3e5941c1 Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 3e5941c1 Giorgos Korfiatis
#      provided with the distribution.
15 3e5941c1 Giorgos Korfiatis
#
16 3e5941c1 Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 3e5941c1 Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 3e5941c1 Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 3e5941c1 Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 3e5941c1 Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 3e5941c1 Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 3e5941c1 Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 3e5941c1 Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 3e5941c1 Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 3e5941c1 Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 3e5941c1 Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 3e5941c1 Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 3e5941c1 Giorgos Korfiatis
#
29 3e5941c1 Giorgos Korfiatis
# The views and conclusions contained in the software and
30 3e5941c1 Giorgos Korfiatis
# documentation are those of the authors and should not be
31 3e5941c1 Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 3e5941c1 Giorgos Korfiatis
# or implied, of GRNET S.A.
33 3e5941c1 Giorgos Korfiatis
34 b0727daf Giorgos Korfiatis
from astakos.quotaholder.exception import (
35 b0727daf Giorgos Korfiatis
    QuotaholderError,
36 b0727daf Giorgos Korfiatis
    CorruptedError, InvalidDataError,
37 1d734153 Giorgos Korfiatis
    NoQuantityError, NoCapacityError,
38 1d734153 Giorgos Korfiatis
    ExportLimitError, ImportLimitError,
39 1d734153 Giorgos Korfiatis
    DuplicateError)
40 fac1de87 Georgios D. Tsoukalas
41 b0727daf Giorgos Korfiatis
from astakos.quotaholder.utils.newname import newname
42 b0727daf Giorgos Korfiatis
from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE
43 f54beeea Giorgos Korfiatis
44 2a3f6a3e Giorgos Korfiatis
from django.db.models import Q, Count
45 1d2b20aa Giorgos Korfiatis
from django.db.models import Q
46 1d2b20aa Giorgos Korfiatis
from .models import (Policy, Holding,
47 8cff5e41 Giorgos Korfiatis
                     Commission, Provision, ProvisionLog,
48 789d202d Giorgos Korfiatis
                     now,
49 1d2b20aa Giorgos Korfiatis
                     db_get_holding, db_get_policy,
50 8cff5e41 Giorgos Korfiatis
                     db_get_commission, db_filter_provision)
51 fac1de87 Georgios D. Tsoukalas
52 e5a2e942 Georgios D. Tsoukalas
53 b0727daf Giorgos Korfiatis
class QuotaholderDjangoDBCallpoint(object):
54 fac1de87 Georgios D. Tsoukalas
55 e3685916 Giorgos Korfiatis
    def get_limits(self, context=None, get_limits=()):
56 fac1de87 Georgios D. Tsoukalas
        limits = []
57 fac1de87 Georgios D. Tsoukalas
        append = limits.append
58 fac1de87 Georgios D. Tsoukalas
59 3f84d70e Christos KK Loverdos
        for policy in get_limits:
60 fac1de87 Georgios D. Tsoukalas
            try:
61 a116d82a Giorgos Korfiatis
                p = Policy.objects.get(policy=policy)
62 fac1de87 Georgios D. Tsoukalas
            except Policy.DoesNotExist:
63 fac1de87 Georgios D. Tsoukalas
                continue
64 fac1de87 Georgios D. Tsoukalas
65 a116d82a Giorgos Korfiatis
            append((policy, p.quantity, p.capacity,
66 a116d82a Giorgos Korfiatis
                    p.import_limit, p.export_limit))
67 fac1de87 Georgios D. Tsoukalas
68 fac1de87 Georgios D. Tsoukalas
        return limits
69 fac1de87 Georgios D. Tsoukalas
70 e3685916 Giorgos Korfiatis
    def set_limits(self, context=None, set_limits=()):
71 fac1de87 Georgios D. Tsoukalas
72 e5a2e942 Georgios D. Tsoukalas
        for (policy, quantity, capacity,
73 e5a2e942 Georgios D. Tsoukalas
             import_limit, export_limit) in set_limits:
74 fac1de87 Georgios D. Tsoukalas
75 e5a2e942 Georgios D. Tsoukalas
            try:
76 e5a2e942 Georgios D. Tsoukalas
                policy = db_get_policy(policy=policy, for_update=True)
77 e5a2e942 Georgios D. Tsoukalas
            except Policy.DoesNotExist:
78 e5a2e942 Georgios D. Tsoukalas
                Policy.objects.create(policy=policy,
79 e5a2e942 Georgios D. Tsoukalas
                                      quantity=quantity,
80 e5a2e942 Georgios D. Tsoukalas
                                      capacity=capacity,
81 e5a2e942 Georgios D. Tsoukalas
                                      import_limit=import_limit,
82 e5a2e942 Georgios D. Tsoukalas
                                      export_limit=export_limit)
83 e5a2e942 Georgios D. Tsoukalas
            else:
84 e5a2e942 Georgios D. Tsoukalas
                policy.quantity = quantity
85 e5a2e942 Georgios D. Tsoukalas
                policy.capacity = capacity
86 e5a2e942 Georgios D. Tsoukalas
                policy.export_limit = export_limit
87 e5a2e942 Georgios D. Tsoukalas
                policy.import_limit = import_limit
88 e5a2e942 Georgios D. Tsoukalas
                policy.save()
89 fac1de87 Georgios D. Tsoukalas
90 fac1de87 Georgios D. Tsoukalas
        return ()
91 fac1de87 Georgios D. Tsoukalas
92 e3685916 Giorgos Korfiatis
    def get_holding(self, context=None, get_holding=()):
93 fac1de87 Georgios D. Tsoukalas
        holdings = []
94 fac1de87 Georgios D. Tsoukalas
        append = holdings.append
95 fac1de87 Georgios D. Tsoukalas
96 8b54001e Giorgos Korfiatis
        for holder, resource in get_holding:
97 fac1de87 Georgios D. Tsoukalas
            try:
98 8b54001e Giorgos Korfiatis
                h = Holding.objects.get(holder=holder, resource=resource)
99 fac1de87 Georgios D. Tsoukalas
            except Holding.DoesNotExist:
100 fac1de87 Georgios D. Tsoukalas
                continue
101 fac1de87 Georgios D. Tsoukalas
102 8b54001e Giorgos Korfiatis
            append((h.holder, h.resource, h.policy.policy,
103 b435047b root
                    h.imported, h.exported,
104 d6662f65 root
                    h.returned, h.released, h.flags))
105 fac1de87 Georgios D. Tsoukalas
106 fac1de87 Georgios D. Tsoukalas
        return holdings
107 fac1de87 Georgios D. Tsoukalas
108 e3685916 Giorgos Korfiatis
    def set_holding(self, context=None, set_holding=()):
109 fac1de87 Georgios D. Tsoukalas
        rejected = []
110 fac1de87 Georgios D. Tsoukalas
        append = rejected.append
111 fac1de87 Georgios D. Tsoukalas
112 8b54001e Giorgos Korfiatis
        for holder, resource, policy, flags in set_holding:
113 fac1de87 Georgios D. Tsoukalas
            try:
114 fac1de87 Georgios D. Tsoukalas
                p = Policy.objects.get(policy=policy)
115 fac1de87 Georgios D. Tsoukalas
            except Policy.DoesNotExist:
116 8b54001e Giorgos Korfiatis
                append((holder, resource, policy))
117 fac1de87 Georgios D. Tsoukalas
                continue
118 fac1de87 Georgios D. Tsoukalas
119 fac1de87 Georgios D. Tsoukalas
            try:
120 8b54001e Giorgos Korfiatis
                h = db_get_holding(holder=holder, resource=resource,
121 5d996aea Giorgos Korfiatis
                                   for_update=True)
122 fac1de87 Georgios D. Tsoukalas
                h.policy = p
123 fac1de87 Georgios D. Tsoukalas
                h.flags = flags
124 fac1de87 Georgios D. Tsoukalas
                h.save()
125 fac1de87 Georgios D. Tsoukalas
            except Holding.DoesNotExist:
126 8b54001e Giorgos Korfiatis
                h = Holding.objects.create(holder=holder, resource=resource,
127 e5a2e942 Georgios D. Tsoukalas
                                           policy=p, flags=flags)
128 fac1de87 Georgios D. Tsoukalas
129 eeba67ab Giorgos Korfiatis
        if rejected:
130 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
131 fac1de87 Georgios D. Tsoukalas
        return rejected
132 fac1de87 Georgios D. Tsoukalas
133 1d734153 Giorgos Korfiatis
    def _init_holding(self,
134 8b54001e Giorgos Korfiatis
                      holder, resource, policy,
135 1d734153 Giorgos Korfiatis
                      imported, exported, returned, released,
136 1d734153 Giorgos Korfiatis
                      flags):
137 5b522bc3 Giorgos Korfiatis
        try:
138 8b54001e Giorgos Korfiatis
            h = db_get_holding(holder=holder, resource=resource,
139 5d996aea Giorgos Korfiatis
                               for_update=True)
140 5b522bc3 Giorgos Korfiatis
        except Holding.DoesNotExist:
141 8b54001e Giorgos Korfiatis
            h = Holding(holder=holder, resource=resource)
142 5b522bc3 Giorgos Korfiatis
143 5b522bc3 Giorgos Korfiatis
        h.policy = policy
144 5b522bc3 Giorgos Korfiatis
        h.flags = flags
145 1d734153 Giorgos Korfiatis
        h.imported = imported
146 e5a2e942 Georgios D. Tsoukalas
        h.importing = imported
147 1d734153 Giorgos Korfiatis
        h.exported = exported
148 e5a2e942 Georgios D. Tsoukalas
        h.exporting = exported
149 1d734153 Giorgos Korfiatis
        h.returned = returned
150 e5a2e942 Georgios D. Tsoukalas
        h.returning = returned
151 1d734153 Giorgos Korfiatis
        h.released = released
152 e5a2e942 Georgios D. Tsoukalas
        h.releasing = released
153 5b522bc3 Giorgos Korfiatis
        h.save()
154 5b522bc3 Giorgos Korfiatis
155 e3685916 Giorgos Korfiatis
    def init_holding(self, context=None, init_holding=()):
156 5b522bc3 Giorgos Korfiatis
        rejected = []
157 5b522bc3 Giorgos Korfiatis
        append = rejected.append
158 5b522bc3 Giorgos Korfiatis
159 a7cdc223 Giorgos Korfiatis
        for idx, sfh in enumerate(init_holding):
160 8b54001e Giorgos Korfiatis
            (holder, resource, policy,
161 5b522bc3 Giorgos Korfiatis
             imported, exported, returned, released,
162 5b522bc3 Giorgos Korfiatis
             flags) = sfh
163 5b522bc3 Giorgos Korfiatis
164 5b522bc3 Giorgos Korfiatis
            try:
165 5b522bc3 Giorgos Korfiatis
                p = Policy.objects.get(policy=policy)
166 5b522bc3 Giorgos Korfiatis
            except Policy.DoesNotExist:
167 5b522bc3 Giorgos Korfiatis
                append(idx)
168 5b522bc3 Giorgos Korfiatis
                continue
169 5b522bc3 Giorgos Korfiatis
170 8b54001e Giorgos Korfiatis
            self._init_holding(holder, resource, p,
171 e5a2e942 Georgios D. Tsoukalas
                               imported, exported,
172 e5a2e942 Georgios D. Tsoukalas
                               returned, released,
173 e5a2e942 Georgios D. Tsoukalas
                               flags)
174 eeba67ab Giorgos Korfiatis
        if rejected:
175 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
176 5b522bc3 Giorgos Korfiatis
        return rejected
177 5b522bc3 Giorgos Korfiatis
178 e3685916 Giorgos Korfiatis
    def reset_holding(self, context=None, reset_holding=()):
179 4c00b904 Giorgos Korfiatis
        rejected = []
180 4c00b904 Giorgos Korfiatis
        append = rejected.append
181 4c00b904 Giorgos Korfiatis
182 4c00b904 Giorgos Korfiatis
        for idx, tpl in enumerate(reset_holding):
183 8b54001e Giorgos Korfiatis
            (holder, resource,
184 4c00b904 Giorgos Korfiatis
             imported, exported, returned, released) = tpl
185 4c00b904 Giorgos Korfiatis
186 4c00b904 Giorgos Korfiatis
            try:
187 8b54001e Giorgos Korfiatis
                h = db_get_holding(holder=holder, resource=resource,
188 5d996aea Giorgos Korfiatis
                                   for_update=True)
189 1d734153 Giorgos Korfiatis
                h.imported = imported
190 e5a2e942 Georgios D. Tsoukalas
                h.importing = imported
191 1d734153 Giorgos Korfiatis
                h.exported = exported
192 e5a2e942 Georgios D. Tsoukalas
                h.exporting = exported
193 1d734153 Giorgos Korfiatis
                h.returned = returned
194 e5a2e942 Georgios D. Tsoukalas
                h.returning = returned
195 1d734153 Giorgos Korfiatis
                h.released = released
196 e5a2e942 Georgios D. Tsoukalas
                h.releasing = released
197 4c00b904 Giorgos Korfiatis
                h.save()
198 4c00b904 Giorgos Korfiatis
            except Holding.DoesNotExist:
199 4c00b904 Giorgos Korfiatis
                append(idx)
200 4c00b904 Giorgos Korfiatis
                continue
201 4c00b904 Giorgos Korfiatis
202 eeba67ab Giorgos Korfiatis
        if rejected:
203 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
204 4c00b904 Giorgos Korfiatis
        return rejected
205 4c00b904 Giorgos Korfiatis
206 8b54001e Giorgos Korfiatis
    def _check_pending(self, holder, resource):
207 8b54001e Giorgos Korfiatis
        cs = Commission.objects.filter(holder=holder)
208 cceadca8 Giorgos Korfiatis
        cs = [c for c in cs if c.provisions.filter(resource=resource)]
209 cceadca8 Giorgos Korfiatis
        as_target = [c.serial for c in cs]
210 8dc7c13b Giorgos Korfiatis
211 8b54001e Giorgos Korfiatis
        ps = Provision.objects.filter(holder=holder, resource=resource)
212 cceadca8 Giorgos Korfiatis
        as_source = [p.serial.serial for p in ps]
213 cceadca8 Giorgos Korfiatis
214 cceadca8 Giorgos Korfiatis
        return as_target + as_source
215 8dc7c13b Giorgos Korfiatis
216 8dc7c13b Giorgos Korfiatis
    def _actual_quantity(self, holding):
217 8dc7c13b Giorgos Korfiatis
        hp = holding.policy
218 8dc7c13b Giorgos Korfiatis
        return hp.quantity + (holding.imported + holding.returned -
219 8dc7c13b Giorgos Korfiatis
                              holding.exported - holding.released)
220 8dc7c13b Giorgos Korfiatis
221 e3685916 Giorgos Korfiatis
    def release_holding(self, context=None, release_holding=()):
222 8dc7c13b Giorgos Korfiatis
        rejected = []
223 8dc7c13b Giorgos Korfiatis
        append = rejected.append
224 8dc7c13b Giorgos Korfiatis
225 8b54001e Giorgos Korfiatis
        for idx, (holder, resource) in enumerate(release_holding):
226 8dc7c13b Giorgos Korfiatis
            try:
227 8b54001e Giorgos Korfiatis
                h = db_get_holding(holder=holder, resource=resource,
228 5d996aea Giorgos Korfiatis
                                   for_update=True)
229 8dc7c13b Giorgos Korfiatis
            except Holding.DoesNotExist:
230 8dc7c13b Giorgos Korfiatis
                append(idx)
231 8dc7c13b Giorgos Korfiatis
                continue
232 8dc7c13b Giorgos Korfiatis
233 8b54001e Giorgos Korfiatis
            if self._check_pending(holder, resource):
234 8dc7c13b Giorgos Korfiatis
                append(idx)
235 8dc7c13b Giorgos Korfiatis
                continue
236 8dc7c13b Giorgos Korfiatis
237 8dc7c13b Giorgos Korfiatis
            q = self._actual_quantity(h)
238 32464501 Giorgos Korfiatis
            if q > 0:
239 1d2b20aa Giorgos Korfiatis
                append(idx)
240 1d2b20aa Giorgos Korfiatis
                continue
241 32464501 Giorgos Korfiatis
242 8dc7c13b Giorgos Korfiatis
            h.delete()
243 8dc7c13b Giorgos Korfiatis
244 eeba67ab Giorgos Korfiatis
        if rejected:
245 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
246 8dc7c13b Giorgos Korfiatis
        return rejected
247 8dc7c13b Giorgos Korfiatis
248 8b54001e Giorgos Korfiatis
    def list_resources(self, context=None, holder=None):
249 8b54001e Giorgos Korfiatis
        holdings = Holding.objects.filter(holder=holder)
250 fac1de87 Georgios D. Tsoukalas
        resources = [h.resource for h in holdings]
251 fac1de87 Georgios D. Tsoukalas
        return resources
252 fac1de87 Georgios D. Tsoukalas
253 e3685916 Giorgos Korfiatis
    def list_holdings(self, context=None, list_holdings=()):
254 65f214a2 Georgios D. Tsoukalas
        rejected = []
255 65f214a2 Georgios D. Tsoukalas
        reject = rejected.append
256 65f214a2 Georgios D. Tsoukalas
        holdings_list = []
257 65f214a2 Georgios D. Tsoukalas
        append = holdings_list.append
258 65f214a2 Georgios D. Tsoukalas
259 8b54001e Giorgos Korfiatis
        for holder in list_holdings:
260 8b54001e Giorgos Korfiatis
            holdings = list(Holding.objects.filter(holder=holder))
261 1d2b20aa Giorgos Korfiatis
            if not holdings:
262 8b54001e Giorgos Korfiatis
                reject(holder)
263 65f214a2 Georgios D. Tsoukalas
                continue
264 65f214a2 Georgios D. Tsoukalas
265 588d107d Giorgos Korfiatis
            append([(holder, h.resource,
266 588d107d Giorgos Korfiatis
                     h.imported, h.exported, h.returned, h.released)
267 1d734153 Giorgos Korfiatis
                    for h in holdings])
268 65f214a2 Georgios D. Tsoukalas
269 65f214a2 Georgios D. Tsoukalas
        return holdings_list, rejected
270 65f214a2 Georgios D. Tsoukalas
271 e3685916 Giorgos Korfiatis
    def get_quota(self, context=None, get_quota=()):
272 fac1de87 Georgios D. Tsoukalas
        quotas = []
273 fac1de87 Georgios D. Tsoukalas
        append = quotas.append
274 fac1de87 Georgios D. Tsoukalas
275 8b54001e Giorgos Korfiatis
        holders = set(holder for holder, r in get_quota)
276 8b54001e Giorgos Korfiatis
        hs = Holding.objects.select_related().filter(holder__in=holders)
277 8acd9708 Giorgos Korfiatis
        holdings = {}
278 8acd9708 Giorgos Korfiatis
        for h in hs:
279 8b54001e Giorgos Korfiatis
            holdings[(h.holder, h.resource)] = h
280 8acd9708 Giorgos Korfiatis
281 8b54001e Giorgos Korfiatis
        for holder, resource in get_quota:
282 fac1de87 Georgios D. Tsoukalas
            try:
283 8b54001e Giorgos Korfiatis
                h = holdings[(holder, resource)]
284 8acd9708 Giorgos Korfiatis
            except:
285 fac1de87 Georgios D. Tsoukalas
                continue
286 fac1de87 Georgios D. Tsoukalas
287 fac1de87 Georgios D. Tsoukalas
            p = h.policy
288 fac1de87 Georgios D. Tsoukalas
289 8b54001e Giorgos Korfiatis
            append((h.holder, h.resource, p.quantity, p.capacity,
290 fac1de87 Georgios D. Tsoukalas
                    p.import_limit, p.export_limit,
291 b435047b root
                    h.imported, h.exported,
292 d6662f65 root
                    h.returned, h.released,
293 b435047b root
                    h.flags))
294 fac1de87 Georgios D. Tsoukalas
295 fac1de87 Georgios D. Tsoukalas
        return quotas
296 fac1de87 Georgios D. Tsoukalas
297 e3685916 Giorgos Korfiatis
    def set_quota(self, context=None, set_quota=()):
298 fac1de87 Georgios D. Tsoukalas
        rejected = []
299 fac1de87 Georgios D. Tsoukalas
        append = rejected.append
300 fac1de87 Georgios D. Tsoukalas
301 2a3f6a3e Giorgos Korfiatis
        q_holdings = Q()
302 8b54001e Giorgos Korfiatis
        holders = []
303 8b54001e Giorgos Korfiatis
        for (holder, resource, _, _, _, _, _) in set_quota:
304 8b54001e Giorgos Korfiatis
            holders.append(holder)
305 2a3f6a3e Giorgos Korfiatis
306 8b54001e Giorgos Korfiatis
        hs = Holding.objects.filter(holder__in=holders).select_for_update()
307 2a3f6a3e Giorgos Korfiatis
        holdings = {}
308 2a3f6a3e Giorgos Korfiatis
        for h in hs:
309 8b54001e Giorgos Korfiatis
            holdings[(h.holder, h.resource)] = h
310 2a3f6a3e Giorgos Korfiatis
311 2a3f6a3e Giorgos Korfiatis
        old_policies = []
312 2a3f6a3e Giorgos Korfiatis
313 8b54001e Giorgos Korfiatis
        for (holder, resource,
314 e5a2e942 Georgios D. Tsoukalas
             quantity, capacity,
315 e5a2e942 Georgios D. Tsoukalas
             import_limit, export_limit, flags) in set_quota:
316 fac1de87 Georgios D. Tsoukalas
317 e5a2e942 Georgios D. Tsoukalas
            policy = newname('policy_')
318 1d734153 Giorgos Korfiatis
            newp = Policy(policy=policy,
319 1d734153 Giorgos Korfiatis
                          quantity=quantity,
320 1d734153 Giorgos Korfiatis
                          capacity=capacity,
321 1d734153 Giorgos Korfiatis
                          import_limit=import_limit,
322 1d734153 Giorgos Korfiatis
                          export_limit=export_limit)
323 fac1de87 Georgios D. Tsoukalas
324 e5a2e942 Georgios D. Tsoukalas
            try:
325 8b54001e Giorgos Korfiatis
                h = holdings[(holder, resource)]
326 2a3f6a3e Giorgos Korfiatis
                old_policies.append(h.policy_id)
327 e5a2e942 Georgios D. Tsoukalas
                h.policy = newp
328 e5a2e942 Georgios D. Tsoukalas
                h.flags = flags
329 2a3f6a3e Giorgos Korfiatis
            except KeyError:
330 8b54001e Giorgos Korfiatis
                h = Holding(holder=holder, resource=resource,
331 e5a2e942 Georgios D. Tsoukalas
                            policy=newp, flags=flags)
332 eec92c03 Georgios D. Tsoukalas
333 e5a2e942 Georgios D. Tsoukalas
            # the order is intentionally reversed so that it
334 e5a2e942 Georgios D. Tsoukalas
            # would break if we are not within a transaction.
335 e5a2e942 Georgios D. Tsoukalas
            # Has helped before.
336 e5a2e942 Georgios D. Tsoukalas
            h.save()
337 e5a2e942 Georgios D. Tsoukalas
            newp.save()
338 8b54001e Giorgos Korfiatis
            holdings[(holder, resource)] = h
339 fac1de87 Georgios D. Tsoukalas
340 2a3f6a3e Giorgos Korfiatis
        objs = Policy.objects.annotate(refs=Count('holding'))
341 2a3f6a3e Giorgos Korfiatis
        objs.filter(policy__in=old_policies, refs=0).delete()
342 fac1de87 Georgios D. Tsoukalas
343 eeba67ab Giorgos Korfiatis
        if rejected:
344 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
345 fac1de87 Georgios D. Tsoukalas
        return rejected
346 fac1de87 Georgios D. Tsoukalas
347 1d734153 Giorgos Korfiatis
    def add_quota(self,
348 8cff5e41 Giorgos Korfiatis
                  context=None,
349 1d734153 Giorgos Korfiatis
                  sub_quota=(), add_quota=()):
350 4ec8c043 Giorgos Korfiatis
        rejected = []
351 4ec8c043 Giorgos Korfiatis
        append = rejected.append
352 4ec8c043 Giorgos Korfiatis
353 2a3f6a3e Giorgos Korfiatis
        sources = sub_quota + add_quota
354 2a3f6a3e Giorgos Korfiatis
        q_holdings = Q()
355 8b54001e Giorgos Korfiatis
        holders = []
356 8b54001e Giorgos Korfiatis
        for (holder, resource, _, _, _, _) in sources:
357 8b54001e Giorgos Korfiatis
            holders.append(holder)
358 2a3f6a3e Giorgos Korfiatis
359 8b54001e Giorgos Korfiatis
        hs = Holding.objects.filter(holder__in=holders).select_for_update()
360 2a3f6a3e Giorgos Korfiatis
        holdings = {}
361 2a3f6a3e Giorgos Korfiatis
        for h in hs:
362 8b54001e Giorgos Korfiatis
            holdings[(h.holder, h.resource)] = h
363 2a3f6a3e Giorgos Korfiatis
364 2a3f6a3e Giorgos Korfiatis
        pids = [h.policy_id for h in hs]
365 2a3f6a3e Giorgos Korfiatis
        policies = Policy.objects.in_bulk(pids)
366 2a3f6a3e Giorgos Korfiatis
367 2a3f6a3e Giorgos Korfiatis
        old_policies = []
368 2a3f6a3e Giorgos Korfiatis
369 d2b32360 Giorgos Korfiatis
        for removing, source in [(True, sub_quota), (False, add_quota)]:
370 8b54001e Giorgos Korfiatis
            for (holder, resource,
371 e5a2e942 Georgios D. Tsoukalas
                 quantity, capacity,
372 e5a2e942 Georgios D. Tsoukalas
                 import_limit, export_limit) in source:
373 4ec8c043 Giorgos Korfiatis
374 e5a2e942 Georgios D. Tsoukalas
                try:
375 8b54001e Giorgos Korfiatis
                    h = holdings[(holder, resource)]
376 2a3f6a3e Giorgos Korfiatis
                    old_policies.append(h.policy_id)
377 2a3f6a3e Giorgos Korfiatis
                    try:
378 2a3f6a3e Giorgos Korfiatis
                        p = policies[h.policy_id]
379 2a3f6a3e Giorgos Korfiatis
                    except KeyError:
380 2a3f6a3e Giorgos Korfiatis
                        raise AssertionError("no policy %s" % h.policy_id)
381 2a3f6a3e Giorgos Korfiatis
                except KeyError:
382 e5a2e942 Georgios D. Tsoukalas
                    if removing:
383 8b54001e Giorgos Korfiatis
                        append((holder, resource))
384 d2b32360 Giorgos Korfiatis
                        continue
385 1d2b20aa Giorgos Korfiatis
386 8b54001e Giorgos Korfiatis
                    h = Holding(holder=holder, resource=resource, flags=0)
387 e5a2e942 Georgios D. Tsoukalas
                    p = None
388 e5a2e942 Georgios D. Tsoukalas
389 e5a2e942 Georgios D. Tsoukalas
                policy = newname('policy_')
390 e5a2e942 Georgios D. Tsoukalas
                newp = Policy(policy=policy)
391 e5a2e942 Georgios D. Tsoukalas
392 e5a2e942 Georgios D. Tsoukalas
                newp.quantity = _add(p.quantity if p else 0, quantity,
393 e5a2e942 Georgios D. Tsoukalas
                                     invert=removing)
394 e5a2e942 Georgios D. Tsoukalas
                newp.capacity = _add(p.capacity if p else 0, capacity,
395 e5a2e942 Georgios D. Tsoukalas
                                     invert=removing)
396 e5a2e942 Georgios D. Tsoukalas
                newp.import_limit = _add(p.import_limit if p else 0,
397 e5a2e942 Georgios D. Tsoukalas
                                         import_limit, invert=removing)
398 e5a2e942 Georgios D. Tsoukalas
                newp.export_limit = _add(p.export_limit if p else 0,
399 e5a2e942 Georgios D. Tsoukalas
                                         export_limit, invert=removing)
400 e5a2e942 Georgios D. Tsoukalas
401 e5a2e942 Georgios D. Tsoukalas
                new_values = [newp.capacity,
402 e5a2e942 Georgios D. Tsoukalas
                              newp.import_limit, newp.export_limit]
403 e5a2e942 Georgios D. Tsoukalas
                if any(map(_isneg, new_values)):
404 8b54001e Giorgos Korfiatis
                    append((holder, resource))
405 e5a2e942 Georgios D. Tsoukalas
                    continue
406 4ec8c043 Giorgos Korfiatis
407 e5a2e942 Georgios D. Tsoukalas
                h.policy = newp
408 4ec8c043 Giorgos Korfiatis
409 e5a2e942 Georgios D. Tsoukalas
                # the order is intentionally reversed so that it
410 e5a2e942 Georgios D. Tsoukalas
                # would break if we are not within a transaction.
411 e5a2e942 Georgios D. Tsoukalas
                # Has helped before.
412 e5a2e942 Georgios D. Tsoukalas
                h.save()
413 e5a2e942 Georgios D. Tsoukalas
                newp.save()
414 2a3f6a3e Giorgos Korfiatis
                policies[policy] = newp
415 8b54001e Giorgos Korfiatis
                holdings[(holder, resource)] = h
416 4ec8c043 Giorgos Korfiatis
417 2a3f6a3e Giorgos Korfiatis
        objs = Policy.objects.annotate(refs=Count('holding'))
418 2a3f6a3e Giorgos Korfiatis
        objs.filter(policy__in=old_policies, refs=0).delete()
419 4ec8c043 Giorgos Korfiatis
420 4ec8c043 Giorgos Korfiatis
        if rejected:
421 b0727daf Giorgos Korfiatis
            raise QuotaholderError(rejected)
422 789d202d Giorgos Korfiatis
423 4ec8c043 Giorgos Korfiatis
        return rejected
424 4ec8c043 Giorgos Korfiatis
425 1d734153 Giorgos Korfiatis
    def issue_commission(self,
426 e3685916 Giorgos Korfiatis
                         context=None,
427 1d734153 Giorgos Korfiatis
                         clientkey=None,
428 1d734153 Giorgos Korfiatis
                         target=None,
429 1d734153 Giorgos Korfiatis
                         name=None,
430 1d734153 Giorgos Korfiatis
                         provisions=()):
431 fac1de87 Georgios D. Tsoukalas
432 c3a709ad root
        create = Commission.objects.create
433 8b54001e Giorgos Korfiatis
        commission = create(holder=target, clientkey=clientkey, name=name)
434 fac1de87 Georgios D. Tsoukalas
        serial = commission.serial
435 fac1de87 Georgios D. Tsoukalas
436 6afede3f Giorgos Korfiatis
        checked = []
437 8b54001e Giorgos Korfiatis
        for holder, resource, quantity in provisions:
438 6afede3f Giorgos Korfiatis
439 8b54001e Giorgos Korfiatis
            if holder == target:
440 8b54001e Giorgos Korfiatis
                m = "Cannot issue commission from an holder to itself (%s)" % (
441 8b54001e Giorgos Korfiatis
                    holder,)
442 4eb170f3 Giorgos Korfiatis
                raise InvalidDataError(m)
443 4eb170f3 Giorgos Korfiatis
444 8b54001e Giorgos Korfiatis
            ent_res = holder, resource
445 6afede3f Giorgos Korfiatis
            if ent_res in checked:
446 6afede3f Giorgos Korfiatis
                m = "Duplicate provision for %s.%s" % ent_res
447 6afede3f Giorgos Korfiatis
                raise DuplicateError(m)
448 6afede3f Giorgos Korfiatis
            checked.append(ent_res)
449 6afede3f Giorgos Korfiatis
450 c3a709ad root
            release = 0
451 c3a709ad root
            if quantity < 0:
452 c3a709ad root
                release = 1
453 c3a709ad root
454 f631150c Giorgos Korfiatis
            # Source limits checks
455 fac1de87 Georgios D. Tsoukalas
            try:
456 8b54001e Giorgos Korfiatis
                h = db_get_holding(holder=holder, resource=resource,
457 5d996aea Giorgos Korfiatis
                                   for_update=True)
458 fac1de87 Georgios D. Tsoukalas
            except Holding.DoesNotExist:
459 d551c841 Georgios D. Tsoukalas
                m = ("There is no quantity "
460 8b54001e Giorgos Korfiatis
                     "to allocate from in %s.%s" % (holder, resource))
461 f631150c Giorgos Korfiatis
                raise NoQuantityError(m,
462 8b54001e Giorgos Korfiatis
                                      source=holder, target=target,
463 f631150c Giorgos Korfiatis
                                      resource=resource, requested=quantity,
464 f631150c Giorgos Korfiatis
                                      current=0, limit=0)
465 fac1de87 Georgios D. Tsoukalas
466 fac1de87 Georgios D. Tsoukalas
            hp = h.policy
467 fac1de87 Georgios D. Tsoukalas
468 d551c841 Georgios D. Tsoukalas
            if not release:
469 d551c841 Georgios D. Tsoukalas
                current = h.exporting
470 d551c841 Georgios D. Tsoukalas
                limit = hp.export_limit
471 d551c841 Georgios D. Tsoukalas
                if current + quantity > limit:
472 8b54001e Giorgos Korfiatis
                    m = ("Export limit reached for %s.%s" % (holder, resource))
473 d551c841 Georgios D. Tsoukalas
                    raise ExportLimitError(m,
474 8b54001e Giorgos Korfiatis
                                           source=holder,
475 e5a2e942 Georgios D. Tsoukalas
                                           target=target,
476 e5a2e942 Georgios D. Tsoukalas
                                           resource=resource,
477 e5a2e942 Georgios D. Tsoukalas
                                           requested=quantity,
478 e5a2e942 Georgios D. Tsoukalas
                                           current=current,
479 e5a2e942 Georgios D. Tsoukalas
                                           limit=limit)
480 d551c841 Georgios D. Tsoukalas
481 d551c841 Georgios D. Tsoukalas
                limit = hp.quantity + h.imported - h.releasing
482 d551c841 Georgios D. Tsoukalas
                unavailable = h.exporting - h.returned
483 d551c841 Georgios D. Tsoukalas
                available = limit - unavailable
484 d551c841 Georgios D. Tsoukalas
485 d551c841 Georgios D. Tsoukalas
                if quantity > available:
486 d551c841 Georgios D. Tsoukalas
                    m = ("There is not enough quantity "
487 8b54001e Giorgos Korfiatis
                         "to allocate from in %s.%s" % (holder, resource))
488 d551c841 Georgios D. Tsoukalas
                    raise NoQuantityError(m,
489 8b54001e Giorgos Korfiatis
                                          source=holder,
490 e5a2e942 Georgios D. Tsoukalas
                                          target=target,
491 e5a2e942 Georgios D. Tsoukalas
                                          resource=resource,
492 e5a2e942 Georgios D. Tsoukalas
                                          requested=quantity,
493 e5a2e942 Georgios D. Tsoukalas
                                          current=unavailable,
494 e5a2e942 Georgios D. Tsoukalas
                                          limit=limit)
495 d551c841 Georgios D. Tsoukalas
            else:
496 d551c841 Georgios D. Tsoukalas
                current = (+ h.importing + h.returning
497 1d734153 Giorgos Korfiatis
                           - h.exported - h.returned)
498 d551c841 Georgios D. Tsoukalas
                limit = hp.capacity
499 d551c841 Georgios D. Tsoukalas
                if current - quantity > limit:
500 d551c841 Georgios D. Tsoukalas
                    m = ("There is not enough capacity "
501 8b54001e Giorgos Korfiatis
                         "to release to in %s.%s" % (holder, resource))
502 d551c841 Georgios D. Tsoukalas
                    raise NoQuantityError(m,
503 8b54001e Giorgos Korfiatis
                                          source=holder,
504 e5a2e942 Georgios D. Tsoukalas
                                          target=target,
505 e5a2e942 Georgios D. Tsoukalas
                                          resource=resource,
506 e5a2e942 Georgios D. Tsoukalas
                                          requested=quantity,
507 e5a2e942 Georgios D. Tsoukalas
                                          current=current,
508 e5a2e942 Georgios D. Tsoukalas
                                          limit=limit)
509 fac1de87 Georgios D. Tsoukalas
510 f631150c Giorgos Korfiatis
            # Target limits checks
511 fac1de87 Georgios D. Tsoukalas
            try:
512 8b54001e Giorgos Korfiatis
                th = db_get_holding(holder=target, resource=resource,
513 5d996aea Giorgos Korfiatis
                                    for_update=True)
514 fac1de87 Georgios D. Tsoukalas
            except Holding.DoesNotExist:
515 ea818d33 Georgios D. Tsoukalas
                m = ("There is no capacity "
516 fac1de87 Georgios D. Tsoukalas
                     "to allocate into in %s.%s" % (target, resource))
517 f631150c Giorgos Korfiatis
                raise NoCapacityError(m,
518 8b54001e Giorgos Korfiatis
                                      source=holder,
519 e5a2e942 Georgios D. Tsoukalas
                                      target=target,
520 e5a2e942 Georgios D. Tsoukalas
                                      resource=resource,
521 e5a2e942 Georgios D. Tsoukalas
                                      requested=quantity,
522 e5a2e942 Georgios D. Tsoukalas
                                      current=0,
523 e5a2e942 Georgios D. Tsoukalas
                                      limit=0)
524 fac1de87 Georgios D. Tsoukalas
525 fac1de87 Georgios D. Tsoukalas
            tp = th.policy
526 fac1de87 Georgios D. Tsoukalas
527 d551c841 Georgios D. Tsoukalas
            if not release:
528 d551c841 Georgios D. Tsoukalas
                limit = tp.import_limit
529 d551c841 Georgios D. Tsoukalas
                current = th.importing
530 d551c841 Georgios D. Tsoukalas
                if current + quantity > limit:
531 d551c841 Georgios D. Tsoukalas
                    m = ("Import limit reached for %s.%s" % (target, resource))
532 d551c841 Georgios D. Tsoukalas
                    raise ImportLimitError(m,
533 8b54001e Giorgos Korfiatis
                                           source=holder,
534 e5a2e942 Georgios D. Tsoukalas
                                           target=target,
535 e5a2e942 Georgios D. Tsoukalas
                                           resource=resource,
536 e5a2e942 Georgios D. Tsoukalas
                                           requested=quantity,
537 e5a2e942 Georgios D. Tsoukalas
                                           current=current,
538 e5a2e942 Georgios D. Tsoukalas
                                           limit=limit)
539 08ce0e6f Giorgos Korfiatis
540 6e4e100b Giorgos Korfiatis
                limit = tp.quantity + tp.capacity
541 6e4e100b Giorgos Korfiatis
                current = (+ th.importing + th.returning + tp.quantity
542 d551c841 Georgios D. Tsoukalas
                           - th.exported - th.released)
543 08ce0e6f Giorgos Korfiatis
544 6e4e100b Giorgos Korfiatis
                if current + quantity > limit:
545 08ce0e6f Giorgos Korfiatis
                    m = ("There is not enough capacity "
546 08ce0e6f Giorgos Korfiatis
                         "to allocate into in %s.%s" % (target, resource))
547 08ce0e6f Giorgos Korfiatis
                    raise NoCapacityError(m,
548 8b54001e Giorgos Korfiatis
                                          source=holder,
549 e5a2e942 Georgios D. Tsoukalas
                                          target=target,
550 e5a2e942 Georgios D. Tsoukalas
                                          resource=resource,
551 e5a2e942 Georgios D. Tsoukalas
                                          requested=quantity,
552 e5a2e942 Georgios D. Tsoukalas
                                          current=current,
553 e5a2e942 Georgios D. Tsoukalas
                                          limit=limit)
554 d551c841 Georgios D. Tsoukalas
            else:
555 d551c841 Georgios D. Tsoukalas
                limit = tp.quantity + th.imported - th.releasing
556 d551c841 Georgios D. Tsoukalas
                unavailable = th.exporting - th.returned
557 d551c841 Georgios D. Tsoukalas
                available = limit - unavailable
558 d551c841 Georgios D. Tsoukalas
559 d551c841 Georgios D. Tsoukalas
                if available + quantity < 0:
560 d551c841 Georgios D. Tsoukalas
                    m = ("There is not enough quantity "
561 d551c841 Georgios D. Tsoukalas
                         "to release from in %s.%s" % (target, resource))
562 d551c841 Georgios D. Tsoukalas
                    raise NoCapacityError(m,
563 8b54001e Giorgos Korfiatis
                                          source=holder,
564 e5a2e942 Georgios D. Tsoukalas
                                          target=target,
565 e5a2e942 Georgios D. Tsoukalas
                                          resource=resource,
566 e5a2e942 Georgios D. Tsoukalas
                                          requested=quantity,
567 e5a2e942 Georgios D. Tsoukalas
                                          current=unavailable,
568 e5a2e942 Georgios D. Tsoukalas
                                          limit=limit)
569 e5a2e942 Georgios D. Tsoukalas
570 1d734153 Giorgos Korfiatis
            Provision.objects.create(serial=commission,
571 8b54001e Giorgos Korfiatis
                                     holder=holder,
572 1d734153 Giorgos Korfiatis
                                     resource=resource,
573 1d734153 Giorgos Korfiatis
                                     quantity=quantity)
574 f590f930 Georgios D. Tsoukalas
            if release:
575 d6662f65 root
                h.returning -= quantity
576 f590f930 Georgios D. Tsoukalas
                th.releasing -= quantity
577 f590f930 Georgios D. Tsoukalas
            else:
578 f590f930 Georgios D. Tsoukalas
                h.exporting += quantity
579 f590f930 Georgios D. Tsoukalas
                th.importing += quantity
580 fac1de87 Georgios D. Tsoukalas
581 fac1de87 Georgios D. Tsoukalas
            h.save()
582 fac1de87 Georgios D. Tsoukalas
            th.save()
583 fac1de87 Georgios D. Tsoukalas
584 fac1de87 Georgios D. Tsoukalas
        return serial
585 fac1de87 Georgios D. Tsoukalas
586 1d734153 Giorgos Korfiatis
    def _log_provision(self,
587 1d734153 Giorgos Korfiatis
                       commission, s_holding, t_holding,
588 1d734153 Giorgos Korfiatis
                       provision, log_time, reason):
589 1dedc367 Georgios D. Tsoukalas
590 8b54001e Giorgos Korfiatis
        s_holder = s_holding.holder
591 d6662f65 root
        s_policy = s_holding.policy
592 8b54001e Giorgos Korfiatis
        t_holder = t_holding.holder
593 d6662f65 root
        t_policy = t_holding.policy
594 1dedc367 Georgios D. Tsoukalas
595 1d734153 Giorgos Korfiatis
        kwargs = {
596 1d734153 Giorgos Korfiatis
            'serial':              commission.serial,
597 1d734153 Giorgos Korfiatis
            'name':                commission.name,
598 8b54001e Giorgos Korfiatis
            'source':              s_holder,
599 8b54001e Giorgos Korfiatis
            'target':              t_holder,
600 1d734153 Giorgos Korfiatis
            'resource':            provision.resource,
601 1d734153 Giorgos Korfiatis
            'source_quantity':     s_policy.quantity,
602 1d734153 Giorgos Korfiatis
            'source_capacity':     s_policy.capacity,
603 1d734153 Giorgos Korfiatis
            'source_import_limit': s_policy.import_limit,
604 1d734153 Giorgos Korfiatis
            'source_export_limit': s_policy.export_limit,
605 1d734153 Giorgos Korfiatis
            'source_imported':     s_holding.imported,
606 1d734153 Giorgos Korfiatis
            'source_exported':     s_holding.exported,
607 1d734153 Giorgos Korfiatis
            'source_returned':     s_holding.returned,
608 1d734153 Giorgos Korfiatis
            'source_released':     s_holding.released,
609 1d734153 Giorgos Korfiatis
            'target_quantity':     t_policy.quantity,
610 1d734153 Giorgos Korfiatis
            'target_capacity':     t_policy.capacity,
611 1d734153 Giorgos Korfiatis
            'target_import_limit': t_policy.import_limit,
612 1d734153 Giorgos Korfiatis
            'target_export_limit': t_policy.export_limit,
613 1d734153 Giorgos Korfiatis
            'target_imported':     t_holding.imported,
614 1d734153 Giorgos Korfiatis
            'target_exported':     t_holding.exported,
615 1d734153 Giorgos Korfiatis
            'target_returned':     t_holding.returned,
616 1d734153 Giorgos Korfiatis
            'target_released':     t_holding.released,
617 1d734153 Giorgos Korfiatis
            'delta_quantity':      provision.quantity,
618 1d734153 Giorgos Korfiatis
            'issue_time':          commission.issue_time,
619 1d734153 Giorgos Korfiatis
            'log_time':            log_time,
620 1d734153 Giorgos Korfiatis
            'reason':              reason,
621 1d734153 Giorgos Korfiatis
        }
622 1d734153 Giorgos Korfiatis
623 1d734153 Giorgos Korfiatis
        ProvisionLog.objects.create(**kwargs)
624 1d734153 Giorgos Korfiatis
625 1d734153 Giorgos Korfiatis
    def accept_commission(self,
626 e3685916 Giorgos Korfiatis
                          context=None, clientkey=None,
627 1d734153 Giorgos Korfiatis
                          serials=(), reason=''):
628 b435047b root
        log_time = now()
629 b435047b root
630 fe6c61fb root
        for serial in serials:
631 fe6c61fb root
            try:
632 5d996aea Giorgos Korfiatis
                c = db_get_commission(clientkey=clientkey, serial=serial,
633 5d996aea Giorgos Korfiatis
                                      for_update=True)
634 fe6c61fb root
            except Commission.DoesNotExist:
635 fe6c61fb root
                return
636 fac1de87 Georgios D. Tsoukalas
637 8b54001e Giorgos Korfiatis
            t = c.holder
638 fac1de87 Georgios D. Tsoukalas
639 5d996aea Giorgos Korfiatis
            provisions = db_filter_provision(serial=serial, for_update=True)
640 fe6c61fb root
            for pv in provisions:
641 fe6c61fb root
                try:
642 8b54001e Giorgos Korfiatis
                    h = db_get_holding(holder=pv.holder,
643 5d996aea Giorgos Korfiatis
                                       resource=pv.resource, for_update=True)
644 8b54001e Giorgos Korfiatis
                    th = db_get_holding(holder=t, resource=pv.resource,
645 5d996aea Giorgos Korfiatis
                                        for_update=True)
646 fe6c61fb root
                except Holding.DoesNotExist:
647 fe6c61fb root
                    m = "Corrupted provision"
648 fe6c61fb root
                    raise CorruptedError(m)
649 fac1de87 Georgios D. Tsoukalas
650 fe6c61fb root
                quantity = pv.quantity
651 fe6c61fb root
                release = 0
652 fe6c61fb root
                if quantity < 0:
653 fe6c61fb root
                    release = 1
654 f590f930 Georgios D. Tsoukalas
655 fe6c61fb root
                if release:
656 d6662f65 root
                    h.returned -= quantity
657 fe6c61fb root
                    th.released -= quantity
658 fe6c61fb root
                else:
659 fe6c61fb root
                    h.exported += quantity
660 fe6c61fb root
                    th.imported += quantity
661 f590f930 Georgios D. Tsoukalas
662 fe6c61fb root
                reason = 'ACCEPT:' + reason[-121:]
663 b435047b root
                self._log_provision(c, h, th, pv, log_time, reason)
664 fe6c61fb root
                h.save()
665 fe6c61fb root
                th.save()
666 fe6c61fb root
                pv.delete()
667 7661c43c Christos Stavrakakis
            c.delete()
668 fac1de87 Georgios D. Tsoukalas
669 fac1de87 Georgios D. Tsoukalas
        return
670 fac1de87 Georgios D. Tsoukalas
671 1d734153 Giorgos Korfiatis
    def reject_commission(self,
672 e3685916 Giorgos Korfiatis
                          context=None, clientkey=None,
673 1d734153 Giorgos Korfiatis
                          serials=(), reason=''):
674 b435047b root
        log_time = now()
675 b435047b root
676 fe6c61fb root
        for serial in serials:
677 fe6c61fb root
            try:
678 5d996aea Giorgos Korfiatis
                c = db_get_commission(clientkey=clientkey, serial=serial,
679 5d996aea Giorgos Korfiatis
                                      for_update=True)
680 fe6c61fb root
            except Commission.DoesNotExist:
681 fe6c61fb root
                return
682 fac1de87 Georgios D. Tsoukalas
683 8b54001e Giorgos Korfiatis
            t = c.holder
684 fac1de87 Georgios D. Tsoukalas
685 5d996aea Giorgos Korfiatis
            provisions = db_filter_provision(serial=serial, for_update=True)
686 fe6c61fb root
            for pv in provisions:
687 fe6c61fb root
                try:
688 8b54001e Giorgos Korfiatis
                    h = db_get_holding(holder=pv.holder,
689 5d996aea Giorgos Korfiatis
                                       resource=pv.resource, for_update=True)
690 8b54001e Giorgos Korfiatis
                    th = db_get_holding(holder=t, resource=pv.resource,
691 5d996aea Giorgos Korfiatis
                                        for_update=True)
692 fe6c61fb root
                except Holding.DoesNotExist:
693 fe6c61fb root
                    m = "Corrupted provision"
694 fe6c61fb root
                    raise CorruptedError(m)
695 fac1de87 Georgios D. Tsoukalas
696 fe6c61fb root
                quantity = pv.quantity
697 fe6c61fb root
                release = 0
698 fe6c61fb root
                if quantity < 0:
699 fe6c61fb root
                    release = 1
700 f590f930 Georgios D. Tsoukalas
701 fe6c61fb root
                if release:
702 d6662f65 root
                    h.returning += quantity
703 fe6c61fb root
                    th.releasing += quantity
704 fe6c61fb root
                else:
705 fe6c61fb root
                    h.exporting -= quantity
706 fe6c61fb root
                    th.importing -= quantity
707 fe6c61fb root
708 fe6c61fb root
                reason = 'REJECT:' + reason[-121:]
709 b435047b root
                self._log_provision(c, h, th, pv, log_time, reason)
710 fe6c61fb root
                h.save()
711 fe6c61fb root
                th.save()
712 fe6c61fb root
                pv.delete()
713 7661c43c Christos Stavrakakis
            c.delete()
714 fac1de87 Georgios D. Tsoukalas
715 fac1de87 Georgios D. Tsoukalas
        return
716 fac1de87 Georgios D. Tsoukalas
717 e3685916 Giorgos Korfiatis
    def get_pending_commissions(self, context=None, clientkey=None):
718 e5a2e942 Georgios D. Tsoukalas
        pending = Commission.objects.filter(clientkey=clientkey)
719 e5a2e942 Georgios D. Tsoukalas
        pending_list = pending.values_list('serial', flat=True)
720 e5a2e942 Georgios D. Tsoukalas
        return pending_list
721 fac1de87 Georgios D. Tsoukalas
722 1d734153 Giorgos Korfiatis
    def resolve_pending_commissions(self,
723 e3685916 Giorgos Korfiatis
                                    context=None, clientkey=None,
724 1d734153 Giorgos Korfiatis
                                    max_serial=None, accept_set=()):
725 fac1de87 Georgios D. Tsoukalas
        accept_set = set(accept_set)
726 e5a2e942 Georgios D. Tsoukalas
        pending = self.get_pending_commissions(context=context,
727 e5a2e942 Georgios D. Tsoukalas
                                               clientkey=clientkey)
728 fac1de87 Georgios D. Tsoukalas
        pending = sorted(pending)
729 fac1de87 Georgios D. Tsoukalas
730 fac1de87 Georgios D. Tsoukalas
        accept = self.accept_commission
731 fac1de87 Georgios D. Tsoukalas
        reject = self.reject_commission
732 fac1de87 Georgios D. Tsoukalas
733 fac1de87 Georgios D. Tsoukalas
        for serial in pending:
734 fac1de87 Georgios D. Tsoukalas
            if serial > max_serial:
735 fac1de87 Georgios D. Tsoukalas
                break
736 fac1de87 Georgios D. Tsoukalas
737 fac1de87 Georgios D. Tsoukalas
            if serial in accept_set:
738 ddf2e911 Giorgos Korfiatis
                accept(context=context, clientkey=clientkey, serials=[serial])
739 fac1de87 Georgios D. Tsoukalas
            else:
740 ddf2e911 Giorgos Korfiatis
                reject(context=context, clientkey=clientkey, serials=[serial])
741 fac1de87 Georgios D. Tsoukalas
742 fac1de87 Georgios D. Tsoukalas
        return
743 fac1de87 Georgios D. Tsoukalas
744 e3685916 Giorgos Korfiatis
    def get_timeline(self, context=None, after="", before="Z", get_timeline=()):
745 8b54001e Giorgos Korfiatis
        holder_set = set()
746 8b54001e Giorgos Korfiatis
        e_add = holder_set.add
747 0360f54b root
        resource_set = set()
748 0360f54b root
        r_add = resource_set.add
749 f590f930 Georgios D. Tsoukalas
750 8b54001e Giorgos Korfiatis
        for holder, resource in get_timeline:
751 8b54001e Giorgos Korfiatis
            if holder not in holder_set:
752 8b54001e Giorgos Korfiatis
                e_add(holder)
753 0360f54b root
754 8b54001e Giorgos Korfiatis
            r_add((holder, resource))
755 f590f930 Georgios D. Tsoukalas
756 f590f930 Georgios D. Tsoukalas
        chunk_size = 65536
757 f590f930 Georgios D. Tsoukalas
        nr = 0
758 f590f930 Georgios D. Tsoukalas
        timeline = []
759 0360f54b root
        append = timeline.append
760 1dedc367 Georgios D. Tsoukalas
        filterlogs = ProvisionLog.objects.filter
761 8b54001e Giorgos Korfiatis
        if holder_set:
762 8b54001e Giorgos Korfiatis
            q_holder = Q(source__in=holder_set) | Q(target__in=holder_set)
763 1dedc367 Georgios D. Tsoukalas
        else:
764 8b54001e Giorgos Korfiatis
            q_holder = Q()
765 1dedc367 Georgios D. Tsoukalas
766 1dedc367 Georgios D. Tsoukalas
        while 1:
767 8b54001e Giorgos Korfiatis
            logs = filterlogs(q_holder,
768 1d734153 Giorgos Korfiatis
                              issue_time__gt=after,
769 1d734153 Giorgos Korfiatis
                              issue_time__lte=before,
770 1d734153 Giorgos Korfiatis
                              reason__startswith='ACCEPT:')
771 f590f930 Georgios D. Tsoukalas
772 f590f930 Georgios D. Tsoukalas
            logs = logs.order_by('issue_time')
773 d6662f65 root
            #logs = logs.values()
774 f590f930 Georgios D. Tsoukalas
            logs = logs[:chunk_size]
775 f590f930 Georgios D. Tsoukalas
            nr += len(logs)
776 f590f930 Georgios D. Tsoukalas
            if not logs:
777 f590f930 Georgios D. Tsoukalas
                break
778 0360f54b root
            for g in logs:
779 0360f54b root
                if ((g.source, g.resource) not in resource_set
780 0360f54b root
                    or (g.target, g.resource) not in resource_set):
781 e5a2e942 Georgios D. Tsoukalas
                    continue
782 0360f54b root
783 d6662f65 root
                o = {
784 1d734153 Giorgos Korfiatis
                    'serial':                   g.serial,
785 1d734153 Giorgos Korfiatis
                    'source':                   g.source,
786 1d734153 Giorgos Korfiatis
                    'target':                   g.target,
787 1d734153 Giorgos Korfiatis
                    'resource':                 g.resource,
788 1d734153 Giorgos Korfiatis
                    'name':                     g.name,
789 1d734153 Giorgos Korfiatis
                    'quantity':                 g.delta_quantity,
790 1d734153 Giorgos Korfiatis
                    'source_allocated':         g.source_allocated(),
791 1d734153 Giorgos Korfiatis
                    'source_allocated_through': g.source_allocated_through(),
792 1d734153 Giorgos Korfiatis
                    'source_inbound':           g.source_inbound(),
793 1d734153 Giorgos Korfiatis
                    'source_inbound_through':   g.source_inbound_through(),
794 1d734153 Giorgos Korfiatis
                    'source_outbound':          g.source_outbound(),
795 1d734153 Giorgos Korfiatis
                    'source_outbound_through':  g.source_outbound_through(),
796 1d734153 Giorgos Korfiatis
                    'target_allocated':         g.target_allocated(),
797 1d734153 Giorgos Korfiatis
                    'target_allocated_through': g.target_allocated_through(),
798 1d734153 Giorgos Korfiatis
                    'target_inbound':           g.target_inbound(),
799 1d734153 Giorgos Korfiatis
                    'target_inbound_through':   g.target_inbound_through(),
800 1d734153 Giorgos Korfiatis
                    'target_outbound':          g.target_outbound(),
801 1d734153 Giorgos Korfiatis
                    'target_outbound_through':  g.target_outbound_through(),
802 1d734153 Giorgos Korfiatis
                    'issue_time':               g.issue_time,
803 1d734153 Giorgos Korfiatis
                    'log_time':                 g.log_time,
804 1d734153 Giorgos Korfiatis
                    'reason':                   g.reason,
805 d6662f65 root
                }
806 d36dcd3d Christos KK Loverdos
807 0360f54b root
                append(o)
808 d6662f65 root
809 d6662f65 root
            after = g.issue_time
810 f590f930 Georgios D. Tsoukalas
            if after >= before:
811 f590f930 Georgios D. Tsoukalas
                break
812 f590f930 Georgios D. Tsoukalas
813 f590f930 Georgios D. Tsoukalas
        return timeline
814 f590f930 Georgios D. Tsoukalas
815 e5a2e942 Georgios D. Tsoukalas
816 d2b32360 Giorgos Korfiatis
def _add(x, y, invert=False):
817 d2b32360 Giorgos Korfiatis
    return x + y if not invert else x - y
818 4ec8c043 Giorgos Korfiatis
819 e5a2e942 Georgios D. Tsoukalas
820 4ec8c043 Giorgos Korfiatis
def _isneg(x):
821 4ec8c043 Giorgos Korfiatis
    return x < 0
822 f590f930 Georgios D. Tsoukalas
823 e5a2e942 Georgios D. Tsoukalas
824 fac1de87 Georgios D. Tsoukalas
API_Callpoint = QuotaholderDjangoDBCallpoint