Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / quotaholder / callpoint.py @ e03ccd07

History | View | Annotate | Download (11.9 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 9747707e Giorgos Korfiatis
from django.db.models import F
35 b0727daf Giorgos Korfiatis
from astakos.quotaholder.exception import (
36 b0727daf Giorgos Korfiatis
    QuotaholderError,
37 79e3da8a Giorgos Korfiatis
    NoCommissionError,
38 b0727daf Giorgos Korfiatis
    CorruptedError, InvalidDataError,
39 79e3da8a Giorgos Korfiatis
    NoHoldingError,
40 1d734153 Giorgos Korfiatis
    DuplicateError)
41 fac1de87 Georgios D. Tsoukalas
42 d03796c2 Giorgos Korfiatis
from astakos.quotaholder.commission import (
43 6c0f4562 Giorgos Korfiatis
    Import, Release, Operations, finalize, undo)
44 d03796c2 Giorgos Korfiatis
45 b0727daf Giorgos Korfiatis
from astakos.quotaholder.utils.newname import newname
46 b0727daf Giorgos Korfiatis
from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE
47 f54beeea Giorgos Korfiatis
48 2b888e60 Giorgos Korfiatis
from .models import (Holding,
49 8cff5e41 Giorgos Korfiatis
                     Commission, Provision, ProvisionLog,
50 6c0f4562 Giorgos Korfiatis
                     now)
51 fac1de87 Georgios D. Tsoukalas
52 e5a2e942 Georgios D. Tsoukalas
53 b0727daf Giorgos Korfiatis
class QuotaholderDjangoDBCallpoint(object):
54 fac1de87 Georgios D. Tsoukalas
55 5afce44d Giorgos Korfiatis
    def get_quota(self, holders=None, sources=None, resources=None):
56 5afce44d Giorgos Korfiatis
        holdings = Holding.objects.all()
57 5afce44d Giorgos Korfiatis
58 5afce44d Giorgos Korfiatis
        if holders is not None:
59 5afce44d Giorgos Korfiatis
            holdings = holdings.filter(holder__in=holders)
60 dc9da5b9 Giorgos Korfiatis
61 dc9da5b9 Giorgos Korfiatis
        if sources is not None:
62 dc9da5b9 Giorgos Korfiatis
            holdings = holdings.filter(source__in=sources)
63 dc9da5b9 Giorgos Korfiatis
64 dc9da5b9 Giorgos Korfiatis
        if resources is not None:
65 dc9da5b9 Giorgos Korfiatis
            holdings = holdings.filter(resource__in=resources)
66 dc9da5b9 Giorgos Korfiatis
67 dc9da5b9 Giorgos Korfiatis
        quotas = {}
68 dc9da5b9 Giorgos Korfiatis
        for holding in holdings:
69 dc9da5b9 Giorgos Korfiatis
            key = (holding.holder, holding.source, holding.resource)
70 dc9da5b9 Giorgos Korfiatis
            value = (holding.limit, holding.imported_min, holding.imported_max)
71 dc9da5b9 Giorgos Korfiatis
            quotas[key] = value
72 dc9da5b9 Giorgos Korfiatis
73 dc9da5b9 Giorgos Korfiatis
        return quotas
74 dc9da5b9 Giorgos Korfiatis
75 befa5997 Giorgos Korfiatis
    def _get_holdings_for_update(self, holding_keys):
76 befa5997 Giorgos Korfiatis
        holding_keys = sorted(holding_keys)
77 dc9da5b9 Giorgos Korfiatis
        holdings = {}
78 befa5997 Giorgos Korfiatis
        for (holder, source, resource) in holding_keys:
79 befa5997 Giorgos Korfiatis
            try:
80 befa5997 Giorgos Korfiatis
                h = Holding.objects.get_for_update(
81 befa5997 Giorgos Korfiatis
                    holder=holder, source=source, resource=resource)
82 befa5997 Giorgos Korfiatis
                holdings[(holder, source, resource)] = h
83 befa5997 Giorgos Korfiatis
            except Holding.DoesNotExist:
84 befa5997 Giorgos Korfiatis
                pass
85 befa5997 Giorgos Korfiatis
        return holdings
86 befa5997 Giorgos Korfiatis
87 befa5997 Giorgos Korfiatis
    def _provisions_to_list(self, provisions):
88 befa5997 Giorgos Korfiatis
        lst = []
89 befa5997 Giorgos Korfiatis
        for provision in provisions:
90 befa5997 Giorgos Korfiatis
            try:
91 befa5997 Giorgos Korfiatis
                holder = provision['holder']
92 befa5997 Giorgos Korfiatis
                source = provision['source']
93 befa5997 Giorgos Korfiatis
                resource = provision['resource']
94 befa5997 Giorgos Korfiatis
                quantity = provision['quantity']
95 befa5997 Giorgos Korfiatis
                key = (holder, source, resource)
96 befa5997 Giorgos Korfiatis
                lst.append((key, quantity))
97 befa5997 Giorgos Korfiatis
            except KeyError:
98 befa5997 Giorgos Korfiatis
                raise InvalidDataError("Malformed provision")
99 befa5997 Giorgos Korfiatis
        return lst
100 befa5997 Giorgos Korfiatis
101 befa5997 Giorgos Korfiatis
    def _mkProvision(self, key, quantity):
102 befa5997 Giorgos Korfiatis
        holder, source, resource = key
103 befa5997 Giorgos Korfiatis
        return {'holder': holder,
104 befa5997 Giorgos Korfiatis
                'source': source,
105 befa5997 Giorgos Korfiatis
                'resource': resource,
106 befa5997 Giorgos Korfiatis
                'quantity': quantity,
107 befa5997 Giorgos Korfiatis
                }
108 befa5997 Giorgos Korfiatis
109 befa5997 Giorgos Korfiatis
    def set_holder_quota(self, quotas):
110 befa5997 Giorgos Korfiatis
        q = self._level_quota_dict(quotas)
111 befa5997 Giorgos Korfiatis
        self.set_quota(q)
112 dc9da5b9 Giorgos Korfiatis
113 befa5997 Giorgos Korfiatis
    def _level_quota_dict(self, quotas):
114 befa5997 Giorgos Korfiatis
        lst = []
115 dc9da5b9 Giorgos Korfiatis
        for holder, holder_quota in quotas.iteritems():
116 dc9da5b9 Giorgos Korfiatis
            for source, source_quota in holder_quota.iteritems():
117 dc9da5b9 Giorgos Korfiatis
                for resource, limit in source_quota.iteritems():
118 befa5997 Giorgos Korfiatis
                    key = (holder, source, resource)
119 befa5997 Giorgos Korfiatis
                    lst.append((key, limit))
120 befa5997 Giorgos Korfiatis
        return lst
121 befa5997 Giorgos Korfiatis
122 befa5997 Giorgos Korfiatis
    def set_quota(self, quotas):
123 befa5997 Giorgos Korfiatis
        holding_keys = [key for (key, limit) in quotas]
124 befa5997 Giorgos Korfiatis
        holdings = self._get_holdings_for_update(holding_keys)
125 befa5997 Giorgos Korfiatis
126 befa5997 Giorgos Korfiatis
        for key, limit in quotas:
127 befa5997 Giorgos Korfiatis
            try:
128 befa5997 Giorgos Korfiatis
                h = holdings[key]
129 befa5997 Giorgos Korfiatis
            except KeyError:
130 befa5997 Giorgos Korfiatis
                holder, source, resource = key
131 befa5997 Giorgos Korfiatis
                h = Holding(holder=holder,
132 befa5997 Giorgos Korfiatis
                            source=source,
133 befa5997 Giorgos Korfiatis
                            resource=resource)
134 befa5997 Giorgos Korfiatis
            h.limit = limit
135 befa5997 Giorgos Korfiatis
            h.save()
136 befa5997 Giorgos Korfiatis
            holdings[key] = h
137 dc9da5b9 Giorgos Korfiatis
138 9747707e Giorgos Korfiatis
    def add_resource_limit(self, source, resource, diff):
139 9747707e Giorgos Korfiatis
        objs = Holding.objects.filter(source=source, resource=resource)
140 9747707e Giorgos Korfiatis
        objs.update(limit=F('limit')+diff)
141 9747707e Giorgos Korfiatis
142 1d734153 Giorgos Korfiatis
    def issue_commission(self,
143 e3685916 Giorgos Korfiatis
                         context=None,
144 1d734153 Giorgos Korfiatis
                         clientkey=None,
145 1d734153 Giorgos Korfiatis
                         name=None,
146 79e3da8a Giorgos Korfiatis
                         force=False,
147 d03796c2 Giorgos Korfiatis
                         provisions=()):
148 fac1de87 Georgios D. Tsoukalas
149 2864e701 Giorgos Korfiatis
        if name is None:
150 2864e701 Giorgos Korfiatis
            name = ""
151 c3a709ad root
        create = Commission.objects.create
152 2864e701 Giorgos Korfiatis
        commission = create(clientkey=clientkey, name=name)
153 fac1de87 Georgios D. Tsoukalas
        serial = commission.serial
154 fac1de87 Georgios D. Tsoukalas
155 d03796c2 Giorgos Korfiatis
        operations = Operations()
156 6afede3f Giorgos Korfiatis
157 befa5997 Giorgos Korfiatis
        provisions = self._provisions_to_list(provisions)
158 befa5997 Giorgos Korfiatis
        keys = [key for (key, value) in provisions]
159 befa5997 Giorgos Korfiatis
        holdings = self._get_holdings_for_update(keys)
160 d03796c2 Giorgos Korfiatis
        try:
161 d03796c2 Giorgos Korfiatis
            checked = []
162 befa5997 Giorgos Korfiatis
            for key, quantity in provisions:
163 79e3da8a Giorgos Korfiatis
                if not isinstance(quantity, (int, long)):
164 79e3da8a Giorgos Korfiatis
                    raise InvalidDataError("Malformed provision")
165 c3a709ad root
166 befa5997 Giorgos Korfiatis
                if key in checked:
167 befa5997 Giorgos Korfiatis
                    m = "Duplicate provision for %s" % str(key)
168 befa5997 Giorgos Korfiatis
                    provision = self._mkProvision(key, quantity)
169 79e3da8a Giorgos Korfiatis
                    raise DuplicateError(m,
170 befa5997 Giorgos Korfiatis
                                         provision=provision)
171 befa5997 Giorgos Korfiatis
                checked.append(key)
172 fac1de87 Georgios D. Tsoukalas
173 d03796c2 Giorgos Korfiatis
                # Target
174 d03796c2 Giorgos Korfiatis
                try:
175 befa5997 Giorgos Korfiatis
                    th = holdings[key]
176 befa5997 Giorgos Korfiatis
                except KeyError:
177 e03ccd07 Giorgos Korfiatis
                    m = ("There is no such holding %s" % str(key))
178 befa5997 Giorgos Korfiatis
                    provision = self._mkProvision(key, quantity)
179 79e3da8a Giorgos Korfiatis
                    raise NoHoldingError(m,
180 79e3da8a Giorgos Korfiatis
                                         provision=provision)
181 d551c841 Georgios D. Tsoukalas
182 d03796c2 Giorgos Korfiatis
                if quantity >= 0:
183 79e3da8a Giorgos Korfiatis
                    operations.prepare(Import, th, quantity, force)
184 fac1de87 Georgios D. Tsoukalas
185 d03796c2 Giorgos Korfiatis
                else: # release
186 d03796c2 Giorgos Korfiatis
                    abs_quantity = -quantity
187 79e3da8a Giorgos Korfiatis
                    operations.prepare(Release, th, abs_quantity, force)
188 d03796c2 Giorgos Korfiatis
189 befa5997 Giorgos Korfiatis
                holdings[key] = th
190 d03796c2 Giorgos Korfiatis
                Provision.objects.create(serial=commission,
191 6c0f4562 Giorgos Korfiatis
                                         holder=th.holder,
192 6c0f4562 Giorgos Korfiatis
                                         source=th.source,
193 6c0f4562 Giorgos Korfiatis
                                         resource=th.resource,
194 d03796c2 Giorgos Korfiatis
                                         quantity=quantity)
195 d03796c2 Giorgos Korfiatis
196 d03796c2 Giorgos Korfiatis
        except QuotaholderError:
197 d03796c2 Giorgos Korfiatis
            operations.revert()
198 d03796c2 Giorgos Korfiatis
            raise
199 fac1de87 Georgios D. Tsoukalas
200 fac1de87 Georgios D. Tsoukalas
        return serial
201 fac1de87 Georgios D. Tsoukalas
202 1d734153 Giorgos Korfiatis
    def _log_provision(self,
203 6c0f4562 Giorgos Korfiatis
                       commission, provision, holding, log_time, reason):
204 1dedc367 Georgios D. Tsoukalas
205 1d734153 Giorgos Korfiatis
        kwargs = {
206 1d734153 Giorgos Korfiatis
            'serial':              commission.serial,
207 1d734153 Giorgos Korfiatis
            'name':                commission.name,
208 2864e701 Giorgos Korfiatis
            'holder':              holding.holder,
209 2864e701 Giorgos Korfiatis
            'source':              holding.source,
210 2864e701 Giorgos Korfiatis
            'resource':            holding.resource,
211 b78f2b29 Giorgos Korfiatis
            'limit':               holding.limit,
212 2864e701 Giorgos Korfiatis
            'imported_min':        holding.imported_min,
213 2864e701 Giorgos Korfiatis
            'imported_max':        holding.imported_max,
214 1d734153 Giorgos Korfiatis
            'delta_quantity':      provision.quantity,
215 1d734153 Giorgos Korfiatis
            'issue_time':          commission.issue_time,
216 1d734153 Giorgos Korfiatis
            'log_time':            log_time,
217 1d734153 Giorgos Korfiatis
            'reason':              reason,
218 1d734153 Giorgos Korfiatis
        }
219 1d734153 Giorgos Korfiatis
220 1d734153 Giorgos Korfiatis
        ProvisionLog.objects.create(**kwargs)
221 1d734153 Giorgos Korfiatis
222 6c0f4562 Giorgos Korfiatis
    def _get_commissions_for_update(self, clientkey, serials):
223 6c0f4562 Giorgos Korfiatis
        cs = Commission.objects.filter(
224 6c0f4562 Giorgos Korfiatis
            clientkey=clientkey, serial__in=serials).select_for_update()
225 b435047b root
226 6c0f4562 Giorgos Korfiatis
        commissions = {}
227 6c0f4562 Giorgos Korfiatis
        for c in cs:
228 6c0f4562 Giorgos Korfiatis
            commissions[c.serial] = c
229 6c0f4562 Giorgos Korfiatis
        return commissions
230 d03796c2 Giorgos Korfiatis
231 6c0f4562 Giorgos Korfiatis
    def _partition_by(self, f, l):
232 6c0f4562 Giorgos Korfiatis
        d = {}
233 6c0f4562 Giorgos Korfiatis
        for x in l:
234 6c0f4562 Giorgos Korfiatis
            group = f(x)
235 6c0f4562 Giorgos Korfiatis
            group_l = d.get(group, [])
236 6c0f4562 Giorgos Korfiatis
            group_l.append(x)
237 6c0f4562 Giorgos Korfiatis
            d[group] = group_l
238 6c0f4562 Giorgos Korfiatis
        return d
239 fac1de87 Georgios D. Tsoukalas
240 6c0f4562 Giorgos Korfiatis
    def resolve_pending_commissions(self,
241 6c0f4562 Giorgos Korfiatis
                                    context=None, clientkey=None,
242 6c0f4562 Giorgos Korfiatis
                                    accept_set=[], reject_set=[],
243 6c0f4562 Giorgos Korfiatis
                                    reason=''):
244 6c0f4562 Giorgos Korfiatis
        actions = dict.fromkeys(accept_set, True)
245 6c0f4562 Giorgos Korfiatis
        conflicting = set()
246 6c0f4562 Giorgos Korfiatis
        for serial in reject_set:
247 6c0f4562 Giorgos Korfiatis
            if actions.get(serial) is True:
248 6c0f4562 Giorgos Korfiatis
                actions.pop(serial)
249 6c0f4562 Giorgos Korfiatis
                conflicting.add(serial)
250 6c0f4562 Giorgos Korfiatis
            else:
251 6c0f4562 Giorgos Korfiatis
                actions[serial] = False
252 f590f930 Georgios D. Tsoukalas
253 6c0f4562 Giorgos Korfiatis
        conflicting = list(conflicting)
254 6c0f4562 Giorgos Korfiatis
        serials = actions.keys()
255 6c0f4562 Giorgos Korfiatis
        commissions = self._get_commissions_for_update(clientkey, serials)
256 6c0f4562 Giorgos Korfiatis
        ps = Provision.objects.filter(serial__in=serials).select_for_update()
257 6c0f4562 Giorgos Korfiatis
        holding_keys = sorted(p.holding_key() for p in ps)
258 6c0f4562 Giorgos Korfiatis
        holdings = self._get_holdings_for_update(holding_keys)
259 6c0f4562 Giorgos Korfiatis
        provisions = self._partition_by(lambda p: p.serial_id, ps)
260 fe6c61fb root
261 6c0f4562 Giorgos Korfiatis
        log_time = now()
262 fac1de87 Georgios D. Tsoukalas
263 6c0f4562 Giorgos Korfiatis
        accepted, rejected, notFound = [], [], []
264 6c0f4562 Giorgos Korfiatis
        for serial, accept in actions.iteritems():
265 6c0f4562 Giorgos Korfiatis
            commission = commissions.get(serial)
266 6c0f4562 Giorgos Korfiatis
            if commission is None:
267 6c0f4562 Giorgos Korfiatis
                notFound.append(serial)
268 6c0f4562 Giorgos Korfiatis
                continue
269 6c0f4562 Giorgos Korfiatis
270 6c0f4562 Giorgos Korfiatis
            accepted.append(serial) if accept else rejected.append(serial)
271 6c0f4562 Giorgos Korfiatis
272 6c0f4562 Giorgos Korfiatis
            ps = provisions.get(serial)
273 6c0f4562 Giorgos Korfiatis
            assert ps is not None
274 6c0f4562 Giorgos Korfiatis
            for pv in ps:
275 6c0f4562 Giorgos Korfiatis
                key = pv.holding_key()
276 6c0f4562 Giorgos Korfiatis
                h = holdings.get(key)
277 6c0f4562 Giorgos Korfiatis
                if h is None:
278 6c0f4562 Giorgos Korfiatis
                    raise CorruptedError("Corrupted provision")
279 6c0f4562 Giorgos Korfiatis
280 6c0f4562 Giorgos Korfiatis
                quantity = pv.quantity
281 6c0f4562 Giorgos Korfiatis
                action = finalize if accept else undo
282 6c0f4562 Giorgos Korfiatis
                if quantity >= 0:
283 6c0f4562 Giorgos Korfiatis
                    action(Import, h, quantity)
284 6c0f4562 Giorgos Korfiatis
                else:  # release
285 6c0f4562 Giorgos Korfiatis
                    action(Release, h, -quantity)
286 6c0f4562 Giorgos Korfiatis
287 6c0f4562 Giorgos Korfiatis
                prefix = 'ACCEPT:' if accept else 'REJECT:'
288 6c0f4562 Giorgos Korfiatis
                comm_reason = prefix + reason[-121:]
289 6c0f4562 Giorgos Korfiatis
                self._log_provision(commission, pv, h, log_time, comm_reason)
290 6c0f4562 Giorgos Korfiatis
                pv.delete()
291 6c0f4562 Giorgos Korfiatis
            commission.delete()
292 6c0f4562 Giorgos Korfiatis
        return accepted, rejected, notFound, conflicting
293 6c0f4562 Giorgos Korfiatis
294 6c0f4562 Giorgos Korfiatis
    def resolve_pending_commission(self, clientkey, serial, accept=True):
295 6c0f4562 Giorgos Korfiatis
        if accept:
296 6c0f4562 Giorgos Korfiatis
            ok, notOk, notF, confl = self.resolve_pending_commissions(
297 6c0f4562 Giorgos Korfiatis
                clientkey=clientkey, accept_set=[serial])
298 6c0f4562 Giorgos Korfiatis
        else:
299 6c0f4562 Giorgos Korfiatis
            notOk, ok, notF, confl = self.resolve_pending_commissions(
300 6c0f4562 Giorgos Korfiatis
                clientkey=clientkey, reject_set=[serial])
301 6c0f4562 Giorgos Korfiatis
302 6c0f4562 Giorgos Korfiatis
        assert notOk == confl == []
303 6c0f4562 Giorgos Korfiatis
        assert ok + notF == [serial]
304 6c0f4562 Giorgos Korfiatis
        return bool(ok)
305 fac1de87 Georgios D. Tsoukalas
306 e3685916 Giorgos Korfiatis
    def get_pending_commissions(self, context=None, clientkey=None):
307 e5a2e942 Georgios D. Tsoukalas
        pending = Commission.objects.filter(clientkey=clientkey)
308 e5a2e942 Georgios D. Tsoukalas
        pending_list = pending.values_list('serial', flat=True)
309 79e3da8a Giorgos Korfiatis
        return list(pending_list)
310 79e3da8a Giorgos Korfiatis
311 79e3da8a Giorgos Korfiatis
    def get_commission(self, clientkey=None, serial=None):
312 79e3da8a Giorgos Korfiatis
        try:
313 79e3da8a Giorgos Korfiatis
            commission = Commission.objects.get(clientkey=clientkey,
314 79e3da8a Giorgos Korfiatis
                                                serial=serial)
315 79e3da8a Giorgos Korfiatis
        except Commission.DoesNotExist:
316 79e3da8a Giorgos Korfiatis
            raise NoCommissionError(serial)
317 79e3da8a Giorgos Korfiatis
318 79e3da8a Giorgos Korfiatis
        objs = Provision.objects.select_related('holding')
319 79e3da8a Giorgos Korfiatis
        provisions = objs.filter(serial=commission)
320 79e3da8a Giorgos Korfiatis
321 79e3da8a Giorgos Korfiatis
        ps = [p.todict() for p in provisions]
322 79e3da8a Giorgos Korfiatis
323 79e3da8a Giorgos Korfiatis
        response = {'serial':     serial,
324 79e3da8a Giorgos Korfiatis
                    'provisions': ps,
325 79e3da8a Giorgos Korfiatis
                    'issue_time': commission.issue_time,
326 79e3da8a Giorgos Korfiatis
                    }
327 79e3da8a Giorgos Korfiatis
        return response
328 79e3da8a Giorgos Korfiatis
329 e5a2e942 Georgios D. Tsoukalas
330 fac1de87 Georgios D. Tsoukalas
API_Callpoint = QuotaholderDjangoDBCallpoint