· 7 years ago · May 07, 2018, 11:00 AM
1kai@ASCUE68-42:~/dev/el/requester$ git log -p
2commit 1c20733a44ac6dddbab329077f835457dca8d6a4
3Author: kai <kai@Compaq-610>
4Date: Sat May 5 22:49:36 2018 +0300
5
6 Ð’ предÑтавление Продукт/Детали добавлена информациÑ, ÑвлÑетÑÑ Ð»Ð¸ он лизингом
7
8diff --git a/requester/templates/banks/products/detail_view.html b/requester/templates/banks/products/detail_view.html
9index eba688c..f58e5c2 100644
10--- a/requester/templates/banks/products/detail_view.html
11+++ b/requester/templates/banks/products/detail_view.html
12@@ -44,6 +44,13 @@
13 <h5>{% trans "ÐŸÐµÐ½Ñ (%)" %}</h5>
14 <p {% if not object.fine %} class="empty" {% endif %}>{{ object|get_attr:'fine' }}</p>
15 <br>
16+ <h5>{% trans "Лизинг" %}</h5>
17+ <p>{% if object.is_leasing %}
18+ {% trans "Да" %}
19+ {% else %}
20+ {% trans "Ðет" %}
21+ {% endif %}</p>
22+ <br>
23 </div>
24 <div class="col-sm-1"></div>
25 <div class="col-sm-3">
26
27commit 88677cc8295a4eca3e39208a4d57ba3fa640fa27
28Author: kai <kai@Compaq-610>
29Date: Sat May 5 22:44:35 2018 +0300
30
31 ИÑправлено поведение кредитного калькулÑтора в разрезах раÑчёта раÑÑрочки, кредита, лизинга
32
33diff --git a/requester/apps/banks/views/products.py b/requester/apps/banks/views/products.py
34index cfa1fce..742a692 100644
35--- a/requester/apps/banks/views/products.py
36+++ b/requester/apps/banks/views/products.py
37@@ -346,6 +346,7 @@ class CreditCalculator(PermissionedViewMixin, ConstantsMixin, FormView):
38 product.first_payment_interval,
39 float(product.redemption_price),
40 min_term=12,
41+ is_leasing=product.is_leasing,
42 )
43 payments = calculation.payments
44 sum_info = [
45diff --git a/requester/apps/contracts/calculations/payments.py b/requester/apps/contracts/calculations/payments.py
46index 5a11704..4edbd2e 100644
47--- a/requester/apps/contracts/calculations/payments.py
48+++ b/requester/apps/contracts/calculations/payments.py
49@@ -11,7 +11,6 @@ from ..constants import VAT_RATE, LAST_PAYMENT_AFTER
50 from .dates import is_holiday, first_nearest_work_day
51 from .base import *
52
53-
54 class MonthlyPayment(object):
55
56 def __init__(self, amount):
57@@ -62,6 +61,8 @@ class DummyPayment(object):
58 return 'body: {}, vat: {}, rate: {}, total: {}'.format(
59 self.body, self.vat, self.rate, self.total)
60
61+ def __repr__(self):
62+ return 'DummyPayment(' + self.__str__() + ')'
63
64 @python_2_unicode_compatible
65 class MonthlyRisePayment(MonthlyPayment):
66@@ -83,12 +84,15 @@ class MonthlyRisePayment(MonthlyPayment):
67
68 @property
69 def rate(self):
70- return round(self.amount * self._rate, 2)
71+ return round(self.amount * self._rate / 100, 2)
72
73 def __str__(self):
74 return 'body: {}, vat: {}, rate: {}, total: {}'.format(
75 self.body, self.vat, self.rate, self.total)
76
77+ def __repr__(self):
78+ return 'MonthlyRisePayment(' + self.__str__() + ')'
79+
80
81 class LastPaymentMixin(object):
82
83@@ -131,6 +135,7 @@ def calculate_payment_dates(date_start, count, first_payment_after=None):
84 def calculate_payments(amount, term, rate, payment_cls, redemption_price_rate,
85 date_start=None, first_payment_after=None,
86 min_term=None, rate_vat=VAT_RATE, is_leasing=False):
87+
88 if is_leasing:
89 last_payment_cls = type(
90 str('{}LastPayment'.format(payment_cls.__name__)),
91@@ -141,18 +146,56 @@ def calculate_payments(amount, term, rate, payment_cls, redemption_price_rate,
92 last_payment_cls = payment_cls
93
94 payment = payment_cls(term, rate, amount, redemption_price_rate, rate_vat=rate_vat)
95- payments_count = int(round(float(amount / (payment.body + payment.vat))))
96+ payments_count = int(round(float(amount) / (payment.body + payment.vat)))
97 payments = [payment for _ in range(payments_count - 1)]
98- last_payment = last_payment_cls(term, rate, amount, redemption_price_rate, rate_vat=rate_vat)
99+
100+ vat = round(amount * VAT_RATE / (1 + VAT_RATE), 2)
101+
102+ amount_no_vat = amount - vat
103+
104+ contract_value_no_vat_rate = amount - vat
105+
106+ redemption_value_no_vat_rate = round(
107+ contract_value_no_vat_rate * redemption_price_rate,
108+ 2,
109+ )
110+
111+ redemption_value_vat_rate = round(redemption_value_no_vat_rate * rate_vat, 2)
112+
113+ redemption_value_full = redemption_value_vat_rate + redemption_value_no_vat_rate
114+
115+ sum_body = payment.body * (payments_count - 1)
116+ sum_vat = payment.vat * (payments_count - 1)
117+
118+ if is_leasing:
119+ last_body = round(
120+ amount_no_vat - sum_body - redemption_value_no_vat_rate,
121+ 2,
122+ )
123+ else:
124+ last_body = round(
125+ amount_no_vat - sum_body - redemption_value_vat_rate,
126+ 2,
127+ )
128+
129+ last_vat = round(
130+ vat - sum_vat - redemption_value_vat_rate,
131+ 2,
132+ )
133+
134+ last_total_no_vat = last_body + payment.rate
135+ last_total = last_total_no_vat + last_vat
136+
137 last_payment = DummyPayment(
138- last_payment.body,
139- last_payment.vat,
140- last_payment.rate,
141- last_payment.rate_vat,
142- last_payment.total,
143- last_payment.vat_total,
144- last_payment.total_no_vat
145+ last_body,
146+ last_vat,
147+ payment.rate,
148+ payment.rate_vat,
149+ last_total,
150+ last_vat,
151+ last_total_no_vat,
152 )
153+
154 payments.append(last_payment)
155
156 if is_leasing and min_term is not None and payments_count < min_term:
157@@ -160,25 +203,24 @@ def calculate_payments(amount, term, rate, payment_cls, redemption_price_rate,
158 payments[-1].total -= dummy_payments_count * 0.01
159 payments.extend([DummyPayment(0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0)
160 for _ in range(dummy_payments_count)])
161- payments_count = min_term
162-
163- redemption_payment = DummyPayment(
164- redemption_value_no_vat(amount, redemption_price_rate),
165- redemption_value_vat(amount, redemption_price_rate),
166- 0.0,
167- 0.0,
168- redemption_value(amount, redemption_price_rate),
169- 0.0,
170- redemption_value_no_vat(amount, redemption_price_rate)
171- )
172- payments.append(redemption_payment)
173+ payments.append(DummyPayment(
174+ redemption_value_no_vat_rate,
175+ redemption_value_vat_rate,
176+ 0.0,
177+ 0.0,
178+ redemption_value_full,
179+ 0.0,
180+ 0.0,
181+ ))
182+ payments_count = min_term + 1
183
184 date_start = date_start or timezone.now().date()
185 dates = calculate_payment_dates(
186 date_start,
187- payments_count,
188+ payments_count - 1,
189 first_payment_after=first_payment_after
190 )
191 date = dates[-1] + timedelta(days=LAST_PAYMENT_AFTER)
192 dates.append(first_nearest_work_day(date))
193- return zip(dates, payments)
194+
195+ return zip(dates, payments)
196\ No newline at end of file
197
198commit ded6f344ffea11ff85650c06fe90f93d73abfbf1
199Author: kai <kai@Compaq-610>
200Date: Sat May 5 22:40:46 2018 +0300
201
202 теперь работает
203
204diff --git a/requester/settings/defaults.py b/requester/settings/defaults.py
205index 48d3012..5cda9b9 100644
206--- a/requester/settings/defaults.py
207+++ b/requester/settings/defaults.py
208@@ -13,7 +13,9 @@ https://docs.djangoproject.com/en/1.11/ref/settings/
209 """
210
211 import os
212+import sys
213 from os.path import abspath, basename, dirname, join, normpath
214+from decouple import config
215
216 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
217 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
218
219commit 18054399bd29f4a5d5871562866df347d87f9796
220Author: kai <kai@Compaq-610>
221Date: Sat May 5 22:03:58 2018 +0300
222
223 Изменена работа Ñ Ð½Ð°Ñтройками:
224 * Ð’ sys.path (пути, откуда проиÑходит по умолчанию import) добавлена apps
225 ** Ðхтунг! Ð’ apps потенциальные грабли. Ðапример, еÑть модуль requests, который
226 теперь (и раньше тоже) Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ, так как в apps Ñвой модуль requests.
227 Я хочу отказатьÑÑ Ð¾Ñ‚ apps в sys.path и импортировать их по абÑолютному пути.
228 Грабли не нужны.
229 * Из settings вынеÑены некоторые конÑтанты в .env (процеÑÑ Ð±ÑƒÐ´ÐµÑ‚ продолжен)
230 * Ð”Ð»Ñ Ñ€ÑƒÐ»Ð¸Ñ‚ конÑтантами модуль python-decople: он добавлен в requirements.txt
231
232diff --git a/requester/settings/defaults.py b/requester/settings/defaults.py
233index af913c6..48d3012 100644
234--- a/requester/settings/defaults.py
235+++ b/requester/settings/defaults.py
236@@ -23,14 +23,18 @@ UPLOAD_DIR = 'uploads'
237 # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
238
239 # SECURITY WARNING: keep the secret key used in production secret!
240-SECRET_KEY = '$dg=2gu2=srw@aeqt$d%=h(8%dhne_64gbc8(#il)s6noxio#2'
241+SECRET_KEY = config('SECRET_KEY')
242
243 # SECURITY WARNING: don't run with debug turned on in production!
244 DEBUG = True
245
246 PROJECT_NAME = basename(BASE_DIR)
247
248-APPS_ROOT = join(BASE_DIR, 'apps')
249+LOG_DIR = config('LOG_DIR')
250+
251+DEBUG_LOG_FILE = join(LOG_DIR, 'debug.log')
252+
253+sys.path.insert(0, join(BASE_DIR, 'apps'))
254
255 # Application definition
256 INSTALLED_APPS = [
257@@ -142,10 +146,10 @@ AUTH_PASSWORD_VALIDATORS = [
258 },
259 ]
260
261-if not os.path.exists('/var/log/requester/debug.log'):
262- if not os.path.exists('/var/log/requester'):
263- os.makedirs('/var/log/requester')
264- open('/var/log/requester/debug.log', 'a').close()
265+if not os.path.exists(DEBUG_LOG_FILE):
266+ if not os.path.exists(LOG_DIR):
267+ os.makedirs(LOG_DIR)
268+ open(DEBUG_LOG_FILE, 'a').close()
269
270 LOGGING = {
271 'disable_existing_loggers': False,
272@@ -165,7 +169,7 @@ LOGGING = {
273 'file': {
274 'level': 'INFO',
275 'class': 'logging.FileHandler',
276- 'filename': '/var/log/requester/debug.log',
277+ 'filename': DEBUG_LOG_FILE,
278 'formatter': 'verbose'
279 },
280 },
281@@ -199,6 +203,7 @@ USE_I18N = True
282
283 USE_TZ = True
284
285+ALLOWED_HOSTS = ('*',)
286
287 # Static files (CSS, JavaScript, Images)
288 # https://docs.djangoproject.com/en/1.11/howto/static-files/
289diff --git a/requirements.txt b/requirements.txt
290index 7099948..2818d17 100644
291--- a/requirements.txt
292+++ b/requirements.txt
293@@ -11,6 +11,7 @@ PyYAML==3.12
294 six==1.10.0
295 django-model-utils==3.0.0
296 django-bootstrap-dynamic-formsets==0.5.0
297+python-decouple==3.1
298 docxtpl==0.3.4
299 numpy==1.13.3
300 redis==2.10.6