PR-41 Формирование заказа Заказчиком

in progress...
remotes/origin/PR-41
booblegum 9 years ago
parent 3293ca41f7
commit 3fa1f40314
  1. 1
      archilance/settings/base.py
  2. 5
      assets/lib/proekton-components/bash/browserify.sh
  3. 1402
      assets/lib/proekton-components/js/build/init_customer_project_create.js
  4. 66
      assets/lib/proekton-components/js/src/init_customer_project_create.js
  5. 21
      projects/models.py
  6. 62
      projects/static/css/customer_project_create.css
  7. 74
      projects/static/img/circle_cross.svg
  8. BIN
      projects/static/img/paper-clip_icon._g.png
  9. BIN
      projects/static/img/paper-clip_icon.png
  10. 14
      projects/static/js/textarea_additional.js
  11. 1
      projects/templates/customer_project_create.html
  12. 276
      projects/templates/customer_project_create_new.html
  13. 2
      projects/urls.py
  14. 82
      projects/views.py
  15. 9
      wallets/admin.py

@ -128,6 +128,7 @@ TEMPLATES = [
'mathfilters.templatetags.mathfilters',
],
'debug': DEBUG,
# 'loaders': [
# ('django.template.loaders.cached.Loader', [
# 'django.template.loaders.filesystem.Loader',

@ -2,6 +2,7 @@
echo "run browserify"
cd ..
source ~/venv/proekton/bin/activate
browserify ./js/src/init.js -o ./js/build/init.js -t babelify
browserify ./js/src/init_user_profile.js -o ./js/build/init_user_profile.js -t babelify
#browserify ./js/src/init.js -o ./js/build/init.js -t babelify
#browserify ./js/src/init_user_profile.js -o ./js/build/init_user_profile.js -t babelify
browserify ./js/src/init_customer_project_create.js -o ./js/build/init_customer_project_create.js -t babelify
#watchify ./js/src/init.js -t babelify -o ./js/build/init.js

@ -0,0 +1,66 @@
import SelectedContainer from './SelectedContainer';
import NoTreeSelect from './NoTreeSelect';
import TreeSelect from './TreeSelect';
import SingleTreeSelect from './SingleTreeSelect'
$(function () {
function createFilterSpecs(url) {
// SPECIALIZATIONS FILTER
let sb_main = new TreeSelect($('#select-box-1'), {url, visible: true});
sb_main.setHeader("Специальность");
let select_container = new SelectedContainer($('#selected-spec'), {obj: sb_main});
sb_main.connectSelectedContainer(select_container);
let sb_1 = new TreeSelect($('#select-box-2'), {obj: sb_main});
let sb_2 = new TreeSelect($('#select-box-3'), {obj: sb_main});
let sb_3 = new TreeSelect($('#select-box-4'), {obj: sb_main});
let sb_4 = new TreeSelect($('#select-box-5'), {obj: sb_main});
sb_main.setNearbySelectBox(sb_1);
sb_1.setNearbySelectBox(sb_2, sb_main);
sb_2.setNearbySelectBox(sb_3, sb_1);
sb_3.setNearbySelectBox(sb_4, sb_2);
sb_4.setNearbySelectBox("", sb_3);
}
function createFilterBuildingClass(url) {
// BUILDING-CLASSIFICATION FILTER
let sb_build_main = new TreeSelect($('#sb-building-classification'), {url, visible:true});
sb_build_main.setHeader("Классификация здания");
let sb_build_1 = new TreeSelect($('#sb-building-sub-classification'), {obj: sb_build_main});
let select_build_container = new SelectedContainer($('#selected-building-classification'), {obj: sb_build_main});
sb_build_main.connectSelectedContainer(select_build_container);
sb_build_main.setNearbySelectBox(sb_build_1);
sb_build_1.setNearbySelectBox("", sb_build_main);
}
function createFilterConstructionType(url) {
let sb_constr_main = new NoTreeSelect($('#sb-construction-type'), {url, visible:true});
sb_constr_main.setHeader("Вид строительства");
let select_constr_type = new SelectedContainer($('#selected-construction-type'), {obj:sb_constr_main, noTree: true});
sb_constr_main.connectSelectedContainer(select_constr_type);
}
function createFilerLocations(url) {
let sb_loc_main = new SingleTreeSelect($('#sb-location-1'), {url, visible:true});
sb_loc_main.setHeader("Местоположение");
let select_loc = new SelectedContainer($('#selected-location'), {obj: sb_loc_main, onlyOne: true});
sb_loc_main.connectSelectedContainer(select_loc);
let sb_loc_1 = new SingleTreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new SingleTreeSelect($('#sb-location-3'), {obj: sb_loc_main});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
}
createFilterSpecs('/api/specializations_flat');
createFilterBuildingClass('/api/building_classifications');
createFilterConstructionType('/api/construction_type');
createFilerLocations('/api/locations_flat');
});

@ -97,21 +97,26 @@ class Project(models.Model, HitCountMixin):
('deleted', 'Удален'),
)
name = models.CharField(max_length=255)
text = models.TextField(blank=True)
customer = models.ForeignKey(User, related_name='customer_projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
specialization = TreeForeignKey(Specialization, related_name='projects')
budget = models.DecimalField(max_digits=10, decimal_places=0)
budget_by_agreement = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES)
customer = models.ForeignKey(User, related_name='customer_projects')
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
specialization = TreeForeignKey(Specialization, related_name='projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
term = models.IntegerField(default=0)
term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour')
text = models.TextField(blank=True)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
cro = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
# FIXME: set deprecated http://djbook.ru/rel1.8/topics/migrations.html#considerations-when-removing-model-fields
work_type = models.IntegerField(default=1, choices=WORK_TYPES)

@ -0,0 +1,62 @@
.description {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4; /* number of lines to show */
line-height: 1.8em; /* fallback */
max-height: 7.2em; /* fallback */
}
textarea.description {
width: 100%;
min-height: 200px;
}
textarea.auto-hint {
color: darkgray;
}
.btn-plus {
/*width: 300px;*/
/*text-overflow: clip;*/
white-space: normal;
padding-left: 18%;
color: #FF0029;
/*height: 80%;*/
line-height: 1em;
font-family: Arial-MT-Regular;
font-size: 12pt;
}
.btn-plus:hover {
color: #FF0029;
}
.btn-plus {
background: url("../img/circle_cross.svg") no-repeat left;
background-position-x: 5px;
}
.upload-new.paper-clip {
padding-left: 45px;
padding-right: 5px;
background: url("../img/paper-clip_icon._g.png") no-repeat left;
background-size: 30px 30px;
width: auto;
}
.upload-new.paper-clip p {
font-size: 12pt;
width: auto;
text-align: right;
}
.documentsChat.mod {
width: auto;
float: none;
display: inline-block;
vertical-align: inherit;
padding: 0;
margin: 0;
}

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="40"
height="40"
viewBox="0 0 39.999999 39.999999"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="circle_cross.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-1.6481695"
inkscape:cy="84.391007"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="975"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1012.3622)">
<circle
style="fill:none;fill-opacity:1;stroke:#ff0029;stroke-width:1;stroke-opacity:0.94117647;stroke-miterlimit:4;stroke-dasharray:none"
id="path4136"
cx="20"
cy="1032.3622"
r="19.790106" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ff0029;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 20,1020.0647 0,24.595"
id="path4138"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4140"
d="m 32.297513,1032.3622 -24.5950211,0"
style="fill:none;fill-rule:evenodd;stroke:#ff0029;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@ -0,0 +1,14 @@
$(function () {
let $area = $('#with-placeholder');
let placeholder = $area.prop("placeholder");
let changed = false;
$area.addClass("auto-hint");
$area.html(placeholder);
$area.on("click", function (e) {
// if (changed) return
console.log("click");
$(e.target).removeClass("auto-hit");
$(e.target).html("");
return true
})
});

@ -107,6 +107,7 @@
<div class="polsF1 disTab">
<div class="col-lg-3 -single-spec-select">
<div class="-bold">{% trans 'project_stage1' %} <span data-tooltip
data-placement="{% tooltip_placement pk=7 %}"
data-placement="{% tooltip_placement pk=7 %}"
title="{% tooltip pk=7 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>

@ -0,0 +1,276 @@
{% extends 'partials/base.html' %}
{% load i18n %}
{% load staticfiles %}
{% block head_css %}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'>
<link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'>
<link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'>
<link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'>
<link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'>
<link rel='stylesheet' href='{% static "css/custom-checkboxes.css" %}'>
<link rel='stylesheet' href='{% static "css/customer_project_create.css" %}'>
{% endblock %}
{% block content %}
{% include 'partials/modals/project_work_type_suggestion.html' %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row mainContent">
<div class="row">
<div class="col-lg-12 allProjects">
<p class="titleScore">Новый заказ</p>
</div>
</div>
<div class="row">
<div class="col-lg-9">
<div class="header">Название заказа
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input value="" name="" class="simple-input"
placeholder="Пример: Дизайн квартиры, Армирование фундамента, Конструкции перекрытия и т.д.">
</div>
<div class="col-lg-3">
</div>
</div>
<div class="row vertical-child">
<div class="col-lg-9">
<div class="" id="select-box-1"></div>
</div>
<div class="col-lg-3">
<div href="#" onclick="return false" data-toggle="modal"
data-target="#projectWorkTypeSuggestionModal"
class="btn btn-simple btn-plus">Нет нужной специальности хочу добавить
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.contractor_specializations.html_name }}"
value="{{ form.contractor_specializations.value }}">
</div>
</div>
</div>
<div style="margin-top: 45px" class="row">
<div class="col-lg-12">
<div class="header">
Подобно опишите задание для / ...
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i> Обязательно
</div>
<textarea style="width: 100%" rows="6" placeholder=
" Пример №1
Разработать архиьектурные решения для жилого дома на основании эскизной проработки
Пример №2
Разработать проект по електроснабжению и освещению гаража"></textarea>
{# <div id="fileUploadContainer" class="upload-new paper-clip">#}
{# <p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p> до 100 файлов#}
{# </div>#}
<div class="documentsChat mod" id="fileUploadContainer">
<div style="display: inline-block;vertical-align: middle;">
<div style="display: inline-block;vertical-align: inherit;" class="upload-new paper-clip">
<p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p>
</div>
<span style="display: inline-block;vertical-align: inherit;">(до 100 файлов)</span>
</div>
<ul style="float: none" class="list-new-new">
<li class="file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input"
style="position: absolute; top: -1000px; left: -1000px">
<p class="file-upload-label"></p>
<div class="file-upload-remove-btn"></div>
</li>
</ul>
</div>
</div>
</div>
<div class="row separator">
<div class="col-lg-12">
<div class="flex">
<span class="header">Показать расширенные настройки</span>
<button class="resButton">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
<div class="border"></div>
</div>
</div>
</div>
<div class="slide active">
<div class="row">
<div class="col-lg-12">
<div class="header">Способ оплаты</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label>
<input type="checkbox"> Безопасная сделка (с резервированием бюджета)
</label>
<div class="description">
Безопасная сделка – это сервис, с помощью которого:
-Заказчики - полностью избавляются от всех финансовых рисков при сотрудничестве с
Исполнителями;
-Исполнители - получают гарантию своевременной оплаты своей работы (выполненной по заданию
точно в срок).
Это сервис и тип оплаты в заказах, в котором сумма оплаты резервируется (перечисляется на
сайт) Заказчиком до начала работы и выплачивается Исполнителю только после успешного
выполнения задания. А в случае некачественного и/или несвоевременного выполнения –
возвращается Заказчику.
Сайт выступает в Безопасных сделках хранителем и гарантом сохранности средств. А в случае
возникновения конфликтов в заказе - Арбитром, независимой третьей Стороной, помогающей
решить проблемы при сотрудничестве и справедливо распорядиться зарезервированной суммой:
-выплатить ее Исполнителю, если работа выполнена своевременно и в полном соответствии с
заданием;
-вернуть Заказчику, если работа не выполнена или нарушены сроки выполнения;
-разделить сумму между Заказчиком и Исполнителем, если работа выполнена частично и без
нарушения сроков.
</div>
</div>
<div class="col-lg-6">
<label>
<input type="checkbox"> Прямая оплата Исполнителю на его кошелек/счет
</label>
<div class="description">
Прямая оплата - это оплата без помощи сайта. Оплаты заказов происходят напрямую исполнителю
на его личный счет или кошелек.
В данном случае сайт не выступает гарантом сохранности средств и не является Арбитром при
спорных вопросах.
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="header ">Бюджет
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="..." class="simple-input" placeholder="Введите сумму" value="">
</div>
<div class="col-lg-3">
<div class="header">Срок
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="..." class="simple-input" placeholder="Введите срок" value="">
</div>
<div class="col-lg-3">
<label>
<input type="checkbox"> Сделать для исполнителей обязательным для заполнения поля цена и
срок
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</label>
</div>
<div class="col-lg-3">
<label>
<input type="checkbox"> Бюджет и срок по договоренности
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</label>
</div>
</div>
<div class="row separator">
<div class="col-lg-12">
<div class="flex">
<div class="border"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<input type="checkbox"> Создать/выбрать объект, прикрепить объект к заказу
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<input name="..." class="simple-input" placeholder="Создайте/Выберите объект" value="">
</div>
<div class="col-lg-6">
<div class="selected-container horizontal" id="selected-obj">
<input type="hidden" name="obj" value="">
</div>
</div>
</div>
<!-- bottom block -->
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
</div>
<div class="vertical-child" id="sb-building-sub-classification">
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden"
name="{{ form.contractor_building_classifications.html_name }}"
value="{{ form.contractor_building_classifications.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden" name="{{ form.contractor_construction_types.html_name }}"
value="{{ form.contractor_construction_types.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="select-box-header vertical-child">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span>
<i class="fa fa-question-circle-o" aria-hidden="true"
title="bla-bla-bla..."></i>
</div>
<div class="custom-check">
<div class="checked"></div>
<div style="display: none" class="not-checked"></div>
<input name="{{ form.cro.html_name }}" type="checkbox" hidden
{% if form.cro.value %} checked{% endif %}>
</div>
</div>
</div> <!-- bottom block -->
<div class="row top-line">
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="РАЗМЕСТИТЬ ЗАКАЗ">
</div>
<div class="col-lg-3 col-lg-offset-6 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="ПРЕДВАРИТЕЛЬНЫЙ ПРОСМОТР">
</div>
</div>
</div> <!-- slide -->
</div> <!-- content -->
</div>
{% endblock %}
{% block js_block %}
<script src='{% static "lib/proekton-components/js/build/init_customer_project_create.js" %}'></script>
{% endblock %}

@ -12,6 +12,7 @@ from .views import (
ContractorPortfolioUpdateView,
CustomerOfferOrderView,
CustomerProjectCreateView,
CustomerProjectCreateViewNew,
CustomerProjectDeleteView,
CustomerProjectEditView,
CustomerProjectRestoreView,
@ -33,6 +34,7 @@ urlpatterns = [
urls.url(r'^$', ProjectFilterView.as_view(), name='project-filter'),
urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'),
urls.url(r'^create_new/$', CustomerProjectCreateViewNew.as_view(), name='customer-project-create'),
urls.url(r'^(?P<pk>\d+)/$', ProjectDetailWithAnswerView.as_view(), name='detail'),
urls.url(r'^(?P<pk>\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'),
urls.url(r'^(?P<pk>\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'),

@ -481,6 +481,88 @@ class CustomerProjectCreateView(BaseMixin, View):
return render(request, self.template_name, context)
class CustomerProjectCreateViewNew(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create_new.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request)
realty_form = self.realty_form(request=request, prefix='realty_form')
work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
context.update({
'form': form,
'realty_form': realty_form,
'work_type_suggestion_form': work_type_suggestion_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST,
request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
form.is_valid()
realty = form.cleaned_data.get('realty')
if realty:
realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
else:
realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False)
project.customer = request.user
project.save()
form.save_m2m()
Order.objects.create(project=project, secure=project.deal_type == 'secure_deal')
for file in request.FILES.getlist('new_files'):
ProjectFile.objects.create(file=file, project=project)
if realty:
realty_form.save()
else:
realty = realty_form.save(commit=False)
realty.user = request.user
realty.save()
realty_form.save_m2m()
project.realty = realty # Connect a realty with a project
project.save()
messages.info(request, 'Проект успешно создан')
redirect_to = reverse('projects:detail', kwargs={'pk': project.pk})
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
if realty_form and realty_form.errors:
messages.info(request, (
'<p>Произошла ошибка (realty_form)</p>'
'<pre>{realty_form}</pre>'
).format(realty_form=pformat(realty_form.errors)))
context = self.get_context_data(**kwargs)
context.update({'form': form, 'realty_form': realty_form})
return render(request, self.template_name, context)
class CustomerProjectEditView(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm

@ -6,7 +6,7 @@ from .models import InvoiceHistory, WithDraw, Transaction, Wallet, PayFromScore
class InvoiceHistoryAdmin(admin.ModelAdmin):
list_display = ('comment', 'sum', 'user', 'balance',)
readonly_fields = InvoiceHistory._meta.get_all_field_names()
readonly_fields = list(map(lambda obj: obj.name, InvoiceHistory._meta.get_fields()))
class WithDrawAdmin(ImportExportModelAdmin):
@ -16,17 +16,18 @@ class WithDrawAdmin(ImportExportModelAdmin):
class WalletAdmin(admin.ModelAdmin):
list_display = ('customer', 'balance', )
readonly_fields = Wallet._meta.get_all_field_names()
# readonly_fields = Wallet._meta.get_all_field_names()
readonly_fields = list(map(lambda obj: obj.name, Wallet._meta.get_fields()))
class TransactionAdmin(admin.ModelAdmin):
list_display = ('customer', 'complete',)
readonly_fields = Transaction._meta.get_all_field_names()
readonly_fields = list(map(lambda obj: obj.name, Transaction._meta.get_fields()))
class PayFromScoreAdmin(admin.ModelAdmin):
list_display = ('customer', 'sum', 'created_at')
readonly_fields = PayFromScore._meta.get_all_field_names()
readonly_fields = list(map(lambda obj: obj.name, PayFromScore._meta.get_fields()))
admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)

Loading…
Cancel
Save