root / snf-cyclades-app / synnefo / quotas / __init__.py @ 6dbd90c0
History | View | Annotate | Download (10.5 kB)
1 | bfe7ba3c | Christos Stavrakakis | # Copyright 2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | bfe7ba3c | Christos Stavrakakis | #
|
3 | bfe7ba3c | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or without
|
4 | bfe7ba3c | Christos Stavrakakis | # modification, are permitted provided that the following conditions
|
5 | bfe7ba3c | Christos Stavrakakis | # are met:
|
6 | bfe7ba3c | Christos Stavrakakis | #
|
7 | bfe7ba3c | Christos Stavrakakis | # 1. Redistributions of source code must retain the above copyright
|
8 | bfe7ba3c | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer.
|
9 | bfe7ba3c | Christos Stavrakakis | #
|
10 | bfe7ba3c | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above copyright
|
11 | bfe7ba3c | Christos Stavrakakis | # notice, this list of conditions and the following disclaimer in the
|
12 | bfe7ba3c | Christos Stavrakakis | # documentation and/or other materials provided with the distribution.
|
13 | bfe7ba3c | Christos Stavrakakis | #
|
14 | bfe7ba3c | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
15 | bfe7ba3c | Christos Stavrakakis | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16 | bfe7ba3c | Christos Stavrakakis | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17 | bfe7ba3c | Christos Stavrakakis | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
18 | bfe7ba3c | Christos Stavrakakis | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19 | bfe7ba3c | Christos Stavrakakis | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20 | bfe7ba3c | Christos Stavrakakis | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21 | bfe7ba3c | Christos Stavrakakis | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22 | bfe7ba3c | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23 | bfe7ba3c | Christos Stavrakakis | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24 | bfe7ba3c | Christos Stavrakakis | # SUCH DAMAGE.
|
25 | bfe7ba3c | Christos Stavrakakis | #
|
26 | bfe7ba3c | Christos Stavrakakis | # The views and conclusions contained in the software and documentation are
|
27 | bfe7ba3c | Christos Stavrakakis | # those of the authors and should not be interpreted as representing official
|
28 | bfe7ba3c | Christos Stavrakakis | # policies, either expressed or implied, of GRNET S.A.
|
29 | bfe7ba3c | Christos Stavrakakis | |
30 | bfe7ba3c | Christos Stavrakakis | from functools import wraps |
31 | bfe7ba3c | Christos Stavrakakis | from contextlib import contextmanager |
32 | bfe7ba3c | Christos Stavrakakis | |
33 | b14f55b5 | Christos Stavrakakis | |
34 | b14f55b5 | Christos Stavrakakis | from synnefo.db.models import QuotaHolderSerial, VirtualMachine, Network |
35 | bfe7ba3c | Christos Stavrakakis | from synnefo.api.faults import OverLimit |
36 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import CYCLADES_USE_QUOTAHOLDER |
37 | 6dbd90c0 | Christos Stavrakakis | |
38 | 6dbd90c0 | Christos Stavrakakis | if CYCLADES_USE_QUOTAHOLDER:
|
39 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import (CYCLADES_QUOTAHOLDER_URL, |
40 | 6dbd90c0 | Christos Stavrakakis | CYCLADES_QUOTAHOLDER_TOKEN) |
41 | 6dbd90c0 | Christos Stavrakakis | from kamaki.clients.quotaholder import QuotaholderClient |
42 | 6dbd90c0 | Christos Stavrakakis | else:
|
43 | 6dbd90c0 | Christos Stavrakakis | from synnefo.settings import (VMS_USER_QUOTA, MAX_VMS_PER_USER, |
44 | 6dbd90c0 | Christos Stavrakakis | NETWORKS_USER_QUOTA, MAX_NETWORKS_PER_USER) |
45 | bfe7ba3c | Christos Stavrakakis | |
46 | dba149f6 | Christos Stavrakakis | from synnefo.lib.quotaholder.api import (NoCapacityError, NoQuantityError) |
47 | dba149f6 | Christos Stavrakakis | from synnefo.lib.commissioning import CallError |
48 | bfe7ba3c | Christos Stavrakakis | |
49 | bfe7ba3c | Christos Stavrakakis | import logging |
50 | bfe7ba3c | Christos Stavrakakis | log = logging.getLogger(__name__) |
51 | bfe7ba3c | Christos Stavrakakis | |
52 | bfe7ba3c | Christos Stavrakakis | |
53 | b14f55b5 | Christos Stavrakakis | class DummySerial(QuotaHolderSerial): |
54 | b14f55b5 | Christos Stavrakakis | accepted = True
|
55 | b14f55b5 | Christos Stavrakakis | rejected = True
|
56 | b14f55b5 | Christos Stavrakakis | pending = True
|
57 | b14f55b5 | Christos Stavrakakis | id = None
|
58 | b14f55b5 | Christos Stavrakakis | |
59 | b14f55b5 | Christos Stavrakakis | def save(*args, **kwargs): |
60 | b14f55b5 | Christos Stavrakakis | pass
|
61 | b14f55b5 | Christos Stavrakakis | |
62 | b14f55b5 | Christos Stavrakakis | |
63 | b14f55b5 | Christos Stavrakakis | class DummyQuotaholderClient(object): |
64 | b14f55b5 | Christos Stavrakakis | def issue_commission(self, **commission_info): |
65 | b14f55b5 | Christos Stavrakakis | provisions = commission_info["provisions"]
|
66 | b14f55b5 | Christos Stavrakakis | userid = commission_info["target"]
|
67 | b14f55b5 | Christos Stavrakakis | for provision in provisions: |
68 | b14f55b5 | Christos Stavrakakis | entity, resource, size = provision |
69 | b14f55b5 | Christos Stavrakakis | if resource == "cyclades.vm": |
70 | b14f55b5 | Christos Stavrakakis | user_vms = VirtualMachine.objects.filter(userid=userid, |
71 | b14f55b5 | Christos Stavrakakis | deleted=False).count()
|
72 | b14f55b5 | Christos Stavrakakis | user_vm_limit = VMS_USER_QUOTA.get(userid, MAX_VMS_PER_USER) |
73 | 718a601d | root | log.debug("Users VMs %s User Limits %s", user_vms,
|
74 | 718a601d | root | user_vm_limit) |
75 | b14f55b5 | Christos Stavrakakis | if user_vms + size >= user_vm_limit:
|
76 | b14f55b5 | Christos Stavrakakis | raise NoQuantityError()
|
77 | b14f55b5 | Christos Stavrakakis | if resource == "cyclades.network.private": |
78 | b14f55b5 | Christos Stavrakakis | user_networks = Network.objects.filter(userid=userid, |
79 | b14f55b5 | Christos Stavrakakis | deleted=False).count()
|
80 | b14f55b5 | Christos Stavrakakis | user_network_limit = NETWORKS_USER_QUOTA.get(userid, |
81 | b14f55b5 | Christos Stavrakakis | MAX_NETWORKS_PER_USER) |
82 | b14f55b5 | Christos Stavrakakis | if user_networks + size >= user_network_limit:
|
83 | b14f55b5 | Christos Stavrakakis | raise NoQuantityError()
|
84 | b14f55b5 | Christos Stavrakakis | |
85 | b14f55b5 | Christos Stavrakakis | return None |
86 | b14f55b5 | Christos Stavrakakis | |
87 | b14f55b5 | Christos Stavrakakis | def accept_commission(self, *args, **kwargs): |
88 | b14f55b5 | Christos Stavrakakis | pass
|
89 | b14f55b5 | Christos Stavrakakis | |
90 | b14f55b5 | Christos Stavrakakis | def reject_commission(self, *args, **kwargs): |
91 | b14f55b5 | Christos Stavrakakis | pass
|
92 | b14f55b5 | Christos Stavrakakis | |
93 | b14f55b5 | Christos Stavrakakis | def get_pending_commissions(self, *args, **kwargs): |
94 | b14f55b5 | Christos Stavrakakis | return []
|
95 | b14f55b5 | Christos Stavrakakis | |
96 | b14f55b5 | Christos Stavrakakis | |
97 | bfe7ba3c | Christos Stavrakakis | @contextmanager
|
98 | bfe7ba3c | Christos Stavrakakis | def get_quota_holder(): |
99 | bfe7ba3c | Christos Stavrakakis | """Context manager for using a QuotaHolder."""
|
100 | 45855947 | Georgios D. Tsoukalas | if CYCLADES_USE_QUOTAHOLDER:
|
101 | 45855947 | Georgios D. Tsoukalas | quotaholder = QuotaholderClient(CYCLADES_QUOTAHOLDER_URL, |
102 | 45855947 | Georgios D. Tsoukalas | token=CYCLADES_QUOTAHOLDER_TOKEN) |
103 | b14f55b5 | Christos Stavrakakis | else:
|
104 | b14f55b5 | Christos Stavrakakis | quotaholder = DummyQuotaholderClient() |
105 | bfe7ba3c | Christos Stavrakakis | |
106 | bfe7ba3c | Christos Stavrakakis | try:
|
107 | bfe7ba3c | Christos Stavrakakis | yield quotaholder
|
108 | bfe7ba3c | Christos Stavrakakis | finally:
|
109 | bfe7ba3c | Christos Stavrakakis | pass
|
110 | bfe7ba3c | Christos Stavrakakis | |
111 | bfe7ba3c | Christos Stavrakakis | |
112 | bfe7ba3c | Christos Stavrakakis | def uses_commission(func): |
113 | bfe7ba3c | Christos Stavrakakis | """Decorator for wrapping functions that needs commission.
|
114 | bfe7ba3c | Christos Stavrakakis |
|
115 | bfe7ba3c | Christos Stavrakakis | All decorated functions must take as first argument the `serials` list in
|
116 | bfe7ba3c | Christos Stavrakakis | order to extend them with the needed serial numbers, as return by the
|
117 | bfe7ba3c | Christos Stavrakakis | Quotaholder
|
118 | bfe7ba3c | Christos Stavrakakis |
|
119 | bfe7ba3c | Christos Stavrakakis | On successful competition of the decorated function, all serials are
|
120 | bfe7ba3c | Christos Stavrakakis | accepted to the quotaholder, otherwise they are rejected.
|
121 | bfe7ba3c | Christos Stavrakakis |
|
122 | bfe7ba3c | Christos Stavrakakis | """
|
123 | bfe7ba3c | Christos Stavrakakis | |
124 | bfe7ba3c | Christos Stavrakakis | @wraps(func)
|
125 | bfe7ba3c | Christos Stavrakakis | def wrapper(*args, **kwargs): |
126 | bfe7ba3c | Christos Stavrakakis | try:
|
127 | bfe7ba3c | Christos Stavrakakis | serials = [] |
128 | bfe7ba3c | Christos Stavrakakis | ret = func(serials, *args, **kwargs) |
129 | bfe7ba3c | Christos Stavrakakis | if serials:
|
130 | bfe7ba3c | Christos Stavrakakis | accept_commission(serials) |
131 | bfe7ba3c | Christos Stavrakakis | return ret
|
132 | e8f2d02d | Christos Stavrakakis | except CallError:
|
133 | bfe7ba3c | Christos Stavrakakis | log.exception("Unexpected error")
|
134 | b14f55b5 | Christos Stavrakakis | raise
|
135 | bfe7ba3c | Christos Stavrakakis | except:
|
136 | bfe7ba3c | Christos Stavrakakis | if serials:
|
137 | bfe7ba3c | Christos Stavrakakis | reject_commission(serials=serials) |
138 | bfe7ba3c | Christos Stavrakakis | raise
|
139 | bfe7ba3c | Christos Stavrakakis | return wrapper
|
140 | bfe7ba3c | Christos Stavrakakis | |
141 | bfe7ba3c | Christos Stavrakakis | |
142 | bfe7ba3c | Christos Stavrakakis | ## FIXME: Wrap the following two functions inside transaction ?
|
143 | 11a54cb9 | Christos Stavrakakis | def accept_commission(serials, update_db=True): |
144 | bfe7ba3c | Christos Stavrakakis | """Accept a list of pending commissions.
|
145 | bfe7ba3c | Christos Stavrakakis |
|
146 | bfe7ba3c | Christos Stavrakakis | @param serials: List of QuotaHolderSerial objects
|
147 | bfe7ba3c | Christos Stavrakakis |
|
148 | bfe7ba3c | Christos Stavrakakis | """
|
149 | 11a54cb9 | Christos Stavrakakis | if update_db:
|
150 | 11a54cb9 | Christos Stavrakakis | for s in serials: |
151 | 11a54cb9 | Christos Stavrakakis | if s.pending:
|
152 | 11a54cb9 | Christos Stavrakakis | s.accepted = True
|
153 | 11a54cb9 | Christos Stavrakakis | s.save() |
154 | bfe7ba3c | Christos Stavrakakis | |
155 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
156 | bfe7ba3c | Christos Stavrakakis | qh.accept_commission(context={}, |
157 | bfe7ba3c | Christos Stavrakakis | clientkey='cyclades',
|
158 | bfe7ba3c | Christos Stavrakakis | serials=[s.serial for s in serials]) |
159 | bfe7ba3c | Christos Stavrakakis | |
160 | bfe7ba3c | Christos Stavrakakis | |
161 | 11a54cb9 | Christos Stavrakakis | def reject_commission(serials, update_db=True): |
162 | bfe7ba3c | Christos Stavrakakis | """Reject a list of pending commissions.
|
163 | bfe7ba3c | Christos Stavrakakis |
|
164 | bfe7ba3c | Christos Stavrakakis | @param serials: List of QuotaHolderSerial objects
|
165 | bfe7ba3c | Christos Stavrakakis |
|
166 | bfe7ba3c | Christos Stavrakakis | """
|
167 | 11a54cb9 | Christos Stavrakakis | if update_db:
|
168 | 11a54cb9 | Christos Stavrakakis | for s in serials: |
169 | 11a54cb9 | Christos Stavrakakis | if s.pending:
|
170 | 11a54cb9 | Christos Stavrakakis | s.rejected = True
|
171 | 11a54cb9 | Christos Stavrakakis | s.save() |
172 | bfe7ba3c | Christos Stavrakakis | |
173 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
174 | bfe7ba3c | Christos Stavrakakis | qh.reject_commission(context={}, |
175 | bfe7ba3c | Christos Stavrakakis | clientkey='cyclades',
|
176 | bfe7ba3c | Christos Stavrakakis | serials=[s.serial for s in serials]) |
177 | bfe7ba3c | Christos Stavrakakis | |
178 | bfe7ba3c | Christos Stavrakakis | |
179 | bfe7ba3c | Christos Stavrakakis | def issue_commission(**commission_info): |
180 | bfe7ba3c | Christos Stavrakakis | """Issue a new commission to the quotaholder.
|
181 | bfe7ba3c | Christos Stavrakakis |
|
182 | bfe7ba3c | Christos Stavrakakis | Issue a new commission to the quotaholder, and create the
|
183 | bfe7ba3c | Christos Stavrakakis | corresponing QuotaHolderSerial object in DB.
|
184 | bfe7ba3c | Christos Stavrakakis |
|
185 | bfe7ba3c | Christos Stavrakakis | """
|
186 | bfe7ba3c | Christos Stavrakakis | |
187 | bfe7ba3c | Christos Stavrakakis | with get_quota_holder() as qh: |
188 | bfe7ba3c | Christos Stavrakakis | try:
|
189 | bfe7ba3c | Christos Stavrakakis | serial = qh.issue_commission(**commission_info) |
190 | bfe7ba3c | Christos Stavrakakis | except (NoCapacityError, NoQuantityError):
|
191 | bfe7ba3c | Christos Stavrakakis | raise OverLimit("Limit exceeded for your account") |
192 | e8f2d02d | Christos Stavrakakis | except CallError as e: |
193 | e8f2d02d | Christos Stavrakakis | if e.call_error in ["NoCapacityError", "NoQuantityError"]: |
194 | e8f2d02d | Christos Stavrakakis | raise OverLimit("Limit exceeded for your account") |
195 | 6dbd90c0 | Christos Stavrakakis | raise
|
196 | bfe7ba3c | Christos Stavrakakis | |
197 | b14f55b5 | Christos Stavrakakis | if serial:
|
198 | b14f55b5 | Christos Stavrakakis | return QuotaHolderSerial.objects.create(serial=serial)
|
199 | 718a601d | root | elif not CYCLADES_USE_QUOTAHOLDER: |
200 | b14f55b5 | Christos Stavrakakis | return DummySerial()
|
201 | b14f55b5 | Christos Stavrakakis | else:
|
202 | b14f55b5 | Christos Stavrakakis | raise Exception("No serial") |
203 | bfe7ba3c | Christos Stavrakakis | |
204 | bfe7ba3c | Christos Stavrakakis | |
205 | bfe7ba3c | Christos Stavrakakis | # Wrapper functions for issuing commissions for each resource type. Each
|
206 | bfe7ba3c | Christos Stavrakakis | # functions creates the `commission_info` dictionary as expected by the
|
207 | bfe7ba3c | Christos Stavrakakis | # `issue_commision` function. Commissions for deleting a resource, are the same
|
208 | bfe7ba3c | Christos Stavrakakis | # as for creating the same resource, but with negative resource sizes.
|
209 | bfe7ba3c | Christos Stavrakakis | |
210 | bfe7ba3c | Christos Stavrakakis | |
211 | bfe7ba3c | Christos Stavrakakis | def issue_vm_commission(user, flavor, delete=False): |
212 | bfe7ba3c | Christos Stavrakakis | resources = get_server_resources(flavor) |
213 | bfe7ba3c | Christos Stavrakakis | commission_info = create_commission(user, resources, delete) |
214 | bfe7ba3c | Christos Stavrakakis | |
215 | bfe7ba3c | Christos Stavrakakis | return issue_commission(**commission_info)
|
216 | bfe7ba3c | Christos Stavrakakis | |
217 | bfe7ba3c | Christos Stavrakakis | |
218 | bfe7ba3c | Christos Stavrakakis | def get_server_resources(flavor): |
219 | bfe7ba3c | Christos Stavrakakis | return {'vm': 1, |
220 | bfe7ba3c | Christos Stavrakakis | 'cpu': flavor.cpu,
|
221 | 457a8ada | Christos Stavrakakis | 'disk': 1073741824 * flavor.disk, # flavor.disk is in GB |
222 | bfe7ba3c | Christos Stavrakakis | # 'public_ip': 1,
|
223 | bfe7ba3c | Christos Stavrakakis | #'disk_template': flavor.disk_template,
|
224 | 5805fbb1 | Christos Stavrakakis | 'ram': 1048576 * flavor.ram} # flavor.ram is in MB |
225 | bfe7ba3c | Christos Stavrakakis | |
226 | bfe7ba3c | Christos Stavrakakis | |
227 | bfe7ba3c | Christos Stavrakakis | def issue_network_commission(user, delete=False): |
228 | bfe7ba3c | Christos Stavrakakis | resources = get_network_resources() |
229 | bfe7ba3c | Christos Stavrakakis | commission_info = create_commission(user, resources, delete) |
230 | bfe7ba3c | Christos Stavrakakis | |
231 | bfe7ba3c | Christos Stavrakakis | return issue_commission(**commission_info)
|
232 | bfe7ba3c | Christos Stavrakakis | |
233 | bfe7ba3c | Christos Stavrakakis | |
234 | bfe7ba3c | Christos Stavrakakis | def get_network_resources(): |
235 | bfe7ba3c | Christos Stavrakakis | return {"network.private": 1} |
236 | bfe7ba3c | Christos Stavrakakis | |
237 | bfe7ba3c | Christos Stavrakakis | |
238 | bfe7ba3c | Christos Stavrakakis | def invert_resources(resources_dict): |
239 | bfe7ba3c | Christos Stavrakakis | return dict((r, -s) for r, s in resources_dict.items()) |
240 | bfe7ba3c | Christos Stavrakakis | |
241 | bfe7ba3c | Christos Stavrakakis | |
242 | bfe7ba3c | Christos Stavrakakis | def create_commission(user, resources, delete=False): |
243 | bfe7ba3c | Christos Stavrakakis | if delete:
|
244 | bfe7ba3c | Christos Stavrakakis | resources = invert_resources(resources) |
245 | 4ac68aaf | Christos Stavrakakis | provisions = [('cyclades', 'cyclades.' + r, s) |
246 | bfe7ba3c | Christos Stavrakakis | for r, s in resources.items()] |
247 | bfe7ba3c | Christos Stavrakakis | return {"context": {}, |
248 | bfe7ba3c | Christos Stavrakakis | "target": user,
|
249 | 4ac68aaf | Christos Stavrakakis | "key": "1", |
250 | bfe7ba3c | Christos Stavrakakis | "clientkey": "cyclades", |
251 | 7ced3e6b | Christos Stavrakakis | #"owner": "",
|
252 | 7ced3e6b | Christos Stavrakakis | #"ownerkey": "1",
|
253 | bfe7ba3c | Christos Stavrakakis | "name": "", |
254 | bfe7ba3c | Christos Stavrakakis | "provisions": provisions}
|
255 | 11a54cb9 | Christos Stavrakakis | |
256 | 11a54cb9 | Christos Stavrakakis | ##
|
257 | 11a54cb9 | Christos Stavrakakis | ## Reconcile pending commissions
|
258 | 11a54cb9 | Christos Stavrakakis | ##
|
259 | 11a54cb9 | Christos Stavrakakis | |
260 | 11a54cb9 | Christos Stavrakakis | |
261 | 11a54cb9 | Christos Stavrakakis | def accept_commissions(accepted): |
262 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
263 | 11a54cb9 | Christos Stavrakakis | qh.accept_commission(context={}, |
264 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
265 | 11a54cb9 | Christos Stavrakakis | serials=accepted) |
266 | 11a54cb9 | Christos Stavrakakis | |
267 | 11a54cb9 | Christos Stavrakakis | |
268 | 11a54cb9 | Christos Stavrakakis | def reject_commissions(rejected): |
269 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
270 | 11a54cb9 | Christos Stavrakakis | qh.reject_commission(context={}, |
271 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
272 | 11a54cb9 | Christos Stavrakakis | serials=rejected) |
273 | 11a54cb9 | Christos Stavrakakis | |
274 | 11a54cb9 | Christos Stavrakakis | |
275 | 11a54cb9 | Christos Stavrakakis | def fix_pending_commissions(): |
276 | 11a54cb9 | Christos Stavrakakis | (accepted, rejected) = resolve_pending_commissions() |
277 | 11a54cb9 | Christos Stavrakakis | |
278 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
279 | 11a54cb9 | Christos Stavrakakis | if accepted:
|
280 | 11a54cb9 | Christos Stavrakakis | qh.accept_commission(context={}, |
281 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
282 | 11a54cb9 | Christos Stavrakakis | serials=accepted) |
283 | 11a54cb9 | Christos Stavrakakis | if rejected:
|
284 | 11a54cb9 | Christos Stavrakakis | qh.reject_commission(context={}, |
285 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades',
|
286 | 11a54cb9 | Christos Stavrakakis | serials=rejected) |
287 | 11a54cb9 | Christos Stavrakakis | |
288 | 11a54cb9 | Christos Stavrakakis | |
289 | 11a54cb9 | Christos Stavrakakis | def resolve_pending_commissions(): |
290 | 11a54cb9 | Christos Stavrakakis | """Resolve quotaholder pending commissions.
|
291 | 11a54cb9 | Christos Stavrakakis |
|
292 | 11a54cb9 | Christos Stavrakakis | Get pending commissions from the quotaholder and resolve them
|
293 | 11a54cb9 | Christos Stavrakakis | to accepted and rejected, according to the state of the
|
294 | 11a54cb9 | Christos Stavrakakis | QuotaHolderSerial DB table. A pending commission in the quotaholder
|
295 | 11a54cb9 | Christos Stavrakakis | can exist in the QuotaHolderSerial table and be either accepted or
|
296 | 11a54cb9 | Christos Stavrakakis | rejected, or can not exist in this table, so it is rejected.
|
297 | 11a54cb9 | Christos Stavrakakis |
|
298 | 11a54cb9 | Christos Stavrakakis | """
|
299 | 11a54cb9 | Christos Stavrakakis | |
300 | 11a54cb9 | Christos Stavrakakis | qh_pending = get_quotaholder_pending() |
301 | 11a54cb9 | Christos Stavrakakis | if not qh_pending: |
302 | 11a54cb9 | Christos Stavrakakis | return ([], [])
|
303 | 11a54cb9 | Christos Stavrakakis | |
304 | 11a54cb9 | Christos Stavrakakis | qh_pending.sort() |
305 | 11a54cb9 | Christos Stavrakakis | min_ = qh_pending[0]
|
306 | 11a54cb9 | Christos Stavrakakis | |
307 | 11a54cb9 | Christos Stavrakakis | serials = QuotaHolderSerial.objects.filter(serial__gte=min_, pending=False)
|
308 | 11a54cb9 | Christos Stavrakakis | accepted = serials.filter(accepted=True).values_list('serial', flat=True) |
309 | 11a54cb9 | Christos Stavrakakis | accepted = filter(lambda x: x in qh_pending, accepted) |
310 | 11a54cb9 | Christos Stavrakakis | |
311 | 11a54cb9 | Christos Stavrakakis | rejected = list(set(qh_pending) - set(accepted)) |
312 | 11a54cb9 | Christos Stavrakakis | |
313 | 11a54cb9 | Christos Stavrakakis | return (accepted, rejected)
|
314 | 11a54cb9 | Christos Stavrakakis | |
315 | 11a54cb9 | Christos Stavrakakis | |
316 | 11a54cb9 | Christos Stavrakakis | def get_quotaholder_pending(): |
317 | 11a54cb9 | Christos Stavrakakis | with get_quota_holder() as qh: |
318 | 11a54cb9 | Christos Stavrakakis | pending_serials = qh.get_pending_commissions(context={}, |
319 | 11a54cb9 | Christos Stavrakakis | clientkey='cyclades')
|
320 | 11a54cb9 | Christos Stavrakakis | return pending_serials |