Das Speichern in der Datenbank funktioniert mit fetch. Allerdings muss die eindeutige Zuordnung durch Primary Key in Address und allen anderen noch korrigiert werden.

master
Ulf Wagner 1 year ago
parent b3c3774f35
commit 45396364bf
  1. 13
      HaushaltDjangoProject/HaushaltDjangoProject/settings.py
  2. 1
      UGSdjangoProject/.idea/UGSdjangoProject.iml
  3. 3
      UGSdjangoProject/UGSdjangoProject/settings.py
  4. 1
      UGSdjangoProject/UGSdjangoProject/urls.py
  5. 43
      UGSdjangoProject/static/main.js
  6. 18
      UGSdjangoProject/templates/registration/login.html
  7. 22
      UGSdjangoProject/ugssim/form.py
  8. 65
      UGSdjangoProject/ugssim/migrations/0002_allgemeinesdata_remove_address_vorname_and_more.py
  9. 54
      UGSdjangoProject/ugssim/migrations/0003_remove_address_geburtstag_remove_address_hausnummer_and_more.py
  10. 22
      UGSdjangoProject/ugssim/migrations/0004_summary_user.py
  11. 95
      UGSdjangoProject/ugssim/models.py
  12. 16
      UGSdjangoProject/ugssim/templates/planungsparameter/lager.html
  13. 6
      UGSdjangoProject/ugssim/templates/planungsparameter/mandantendaten.html
  14. 50
      UGSdjangoProject/ugssim/templates/planungsparameter/planungsparameter.html
  15. 28
      UGSdjangoProject/ugssim/templates/planungsparameter/pp2.html
  16. 3
      UGSdjangoProject/ugssim/templates/ugssim/address.html
  17. 1
      UGSdjangoProject/ugssim/templates/ugssim/head.html
  18. 11
      UGSdjangoProject/ugssim/templates/ugssim/home.html
  19. 10
      UGSdjangoProject/ugssim/templates/ugssim/logout.html
  20. 8
      UGSdjangoProject/ugssim/templates/ugssim/ugssim.html
  21. 1
      UGSdjangoProject/ugssim/urls.py
  22. 65
      UGSdjangoProject/ugssim/views.py

@ -35,6 +35,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'windows_auth',
"huel.apps.HuelConfig"
]
@ -46,6 +47,8 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'windows_auth.middleware.UserSyncMiddleware',
]
ROOT_URLCONF = 'HaushaltDjangoProject.urls'
@ -113,6 +116,16 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
WAUTH_DOMAINS = {
"SMWK-AD": { # this is your domain's NetBIOS Name, same as in "EXAMPLE\\username" login scheme
"SERVER": "smwk.sachsen.de", # the FQDN of the DC server, usually is the FQDN of the domain itself
"SEARCH_BASE": "DC=example,DC=local", # the default Search Base to use when searching
"USERNAME": "SMWK-AD\\bind_account", # username of the account used to authenticate your Django project to Active Directory
"PASSWORD": "<super secret>", # password for the binding account
}
}
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/

@ -27,6 +27,7 @@
<option value="$MODULE_DIR$/ugssim/templates/ugssim" />
<option value="$MODULE_DIR$/ugssim/templates" />
<option value="$MODULE_DIR$/ugssim/templates/planungsparameter" />
<option value="$MODULE_DIR$/templates/registration" />
</list>
</option>
</component>

@ -126,3 +126,6 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
DATE_FORMAT = '%Y-%m-%d'
DATE_INPUT_FORMATS = '%Y-%m-%d'
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"

@ -22,5 +22,6 @@ from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")), # new
path('', include('ugssim.urls')),
]

@ -0,0 +1,43 @@
const test = () => console.log("Hallo Welten!");
function convertToJsonDict(form) {
let formData = {};
for (let i = 0; i < form.elements.length; i++) {
let element = form.elements[i];
if (element.type !== "submit" && element.type !== "button" &&
element.name !== "csrfmiddlewaretoken") {
formData[element.name] = element.value;
}
}
return formData;
}
const saveAddress = (htmlform) => {
let headers = {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json',
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
console.log("!!!!");
console.log("Änderung: ",htmlform);
let formName = htmlform.getAttribute("name").slice(4);
//console.log("Formname: ",formName);
let jsonFormDict = convertToJsonDict(htmlform)
console.log("JSONDict: ",jsonFormDict)
let bodyDict = {"modelName": formName}
bodyDict['data'] = convertToJsonDict(htmlform)
console.log("bodyDict ",bodyDict)
let body = JSON.stringify(bodyDict)
console.log("Body: ",body)
let response = fetch('/save_planungsparameter/', {
method: 'POST',
headers: headers,
body: body
}
)
}
// https://www.parvatiandsons.in/resource/how-to-add-onchange-event-in-django-python/

@ -0,0 +1,18 @@
{% extends 'ugssim/ugssim.html' %}
{% block title %}Login{% endblock %}
{% block content %}
<h2>Log In</h2>
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Login</button>
</form>
Anleitung dazu
<a href="https://learndjango.com/tutorials/django-login-and-logout-tutorial" target="_blank ">https://learndjango.com/tutorials/django-login-and-logout-tutorial</a>
{% endblock %}
<!--
https://learndjango.com/tutorials/django-login-and-logout-tutorial
-->

@ -27,18 +27,25 @@ class UGSModelForm(forms.ModelForm):
class AddressForm(UGSModelForm):
class Meta:
model = Address
fields = '__all__'
# die ID muss hier wieder rein, weil sonst die Zuordnung nicht klappt oder die user ID muss primaery key werden
fields = ['user', 'first_name', 'surname', 'birthday', 'street', 'number', 'postcode', 'city']
widgets = {
'geburtstag': forms.DateInput(
'birthday': forms.DateInput(
format='%Y-%m-%d',
attrs={ # 'class': 'form-control',
attrs={
'type': 'date'
}
),
#'user': forms.HiddenInput()
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Fügt onchange zu allen Formularfeldern hinzu.
for field in self.fields:
self.fields[field].widget.attrs.update({'onchange': 'saveAddress(this.form)'})
# self.fields['user'].queryset = User.objects.none()
class SummaryForm(UGSModelForm):
class Meta:
@ -47,6 +54,11 @@ class SummaryForm(UGSModelForm):
widgets = {
'text': forms.Textarea(attrs={'rows': 10})
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Fügt onchange zu allen Formularfeldern hinzu.
for field in self.fields:
self.fields[field].widget.attrs.update({'onchange': 'saveAddress(this.form)'})
class SalesAreaTypeForm(UGSModelForm):

@ -0,0 +1,65 @@
# Generated by Django 4.1.2 on 2024-09-10 07:02
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('ugssim', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AllgemeinesData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('currency', models.CharField(max_length=3)),
('years', models.IntegerField()),
('startPhase', models.IntegerField()),
('planingPeriods', models.IntegerField()),
],
),
migrations.RemoveField(
model_name='address',
name='vorname',
),
migrations.AddField(
model_name='address',
name='first_name',
field=models.CharField(max_length=255, null=True, verbose_name='Vorname'),
),
migrations.AddField(
model_name='address',
name='user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='new_spending', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='address',
name='geburtstag',
field=models.DateField(null=True),
),
migrations.AlterField(
model_name='address',
name='hausnummer',
field=models.CharField(max_length=10, null=True),
),
migrations.AlterField(
model_name='address',
name='nachname',
field=models.CharField(max_length=255, null=True),
),
migrations.AlterField(
model_name='address',
name='postleitzahl',
field=models.CharField(max_length=5, null=True),
),
migrations.AlterField(
model_name='address',
name='street',
field=models.CharField(max_length=255, null=True, verbose_name='Straße'),
),
]

@ -0,0 +1,54 @@
# Generated by Django 4.1.2 on 2024-09-10 10:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ugssim', '0002_allgemeinesdata_remove_address_vorname_and_more'),
]
operations = [
migrations.RemoveField(
model_name='address',
name='geburtstag',
),
migrations.RemoveField(
model_name='address',
name='hausnummer',
),
migrations.RemoveField(
model_name='address',
name='nachname',
),
migrations.RemoveField(
model_name='address',
name='postleitzahl',
),
migrations.AddField(
model_name='address',
name='birthday',
field=models.DateField(null=True, verbose_name='Geburtstag'),
),
migrations.AddField(
model_name='address',
name='city',
field=models.CharField(max_length=100, null=True, verbose_name='Stadt'),
),
migrations.AddField(
model_name='address',
name='number',
field=models.CharField(max_length=10, null=True, verbose_name='Hausnummer'),
),
migrations.AddField(
model_name='address',
name='postcode',
field=models.CharField(max_length=5, null=True, verbose_name='Postleitzahl'),
),
migrations.AddField(
model_name='address',
name='surname',
field=models.CharField(max_length=255, null=True, verbose_name='Nachname'),
),
]

@ -0,0 +1,22 @@
# Generated by Django 4.1.2 on 2024-09-12 14:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('ugssim', '0003_remove_address_geburtstag_remove_address_hausnummer_and_more'),
]
operations = [
migrations.AddField(
model_name='summary',
name='user',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='user_summary', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
]

@ -2,24 +2,28 @@ from datetime import date
from django import forms
from django.db import models
from django.contrib.auth.models import User
from UGSdjangoProject import settings
# Create your models here.
class Address(models.Model):
vorname = models.CharField(max_length=255)
nachname = models.CharField(max_length=255)
geburtstag :date = models.DateField()
street = models.CharField(max_length=10)
hausnummer = models.CharField(max_length=255)
postleitzahl = models.CharField(max_length=5)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="new_spending", null=True)
first_name = models.CharField("Vorname", max_length=255, null=True)
surname = models.CharField("Nachname", max_length=255, null=True)
birthday: date = models.DateField("Geburtstag", null=True)
street = models.CharField("Straße", max_length=255, null=True)
number = models.CharField("Hausnummer", max_length=10, null=True)
postcode = models.CharField("Postleitzahl", max_length=5, null=True)
city = models.CharField("Stadt", max_length=100, null=True)
def __str__(self):
return f'{self.vorname} {self.nachname} lives at {self.street} {self.hausnummer}, {self.postleitzahl}'
return f'{self.first_name} {self.surname} lives at {self.street} {self.number}, {self.postcode} {self.city}'
class Summary(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_summary")
text = models.TextField(max_length=2000)
def __str__(self):
@ -40,3 +44,80 @@ class CompanyData(models.Model):
website = models.URLField(max_length=200)
startDate = models.DateField()
#salesArea = models.ManyToManyField(SalesArea, related_name='+')
class AllgemeinesData(models.Model):
currency = models.CharField(max_length=3)
years = models.IntegerField()
startPhase = models.IntegerField()
planingPeriods = models.IntegerField()
'''
Grundsätzloich werden die Daten für den Absatz in das Jahresfeld eingegeben
Bei eingabe in dieses Feld werden die Monatswerte überschrieben/gesetzt
Der Nutzer kann aber auch werte in die einzelnen Monate eintragen
Dies werden dann zum Jahr aufsummiert
Umsatz wir berechnet: Menge x Preis
'''
'''
class Revenue(models.Model):
unit = models.CharField(max_length=255)
value = models.DecimalField(max_digits=10, decimal_places=2)
year = models.IntegerField()
class revenueField(models.Model):
title = models.CharField(max_length=255)
# MWST Satz
# REvenue 1 : n
class SalesMarketing(models.Model):
# Revneue 1: 1 ?
class BeschaffungsItem(models.Model):
title = models.CharField(max_length=255)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantityDependent = models.IntegerField() # True or False
quantity = models.IntegerField()
# Mehrfach für jedes RvenueField
class Invest(models.Model):
anschaffungsKosten=models.DecimalField(max_digits=10, decimal_places=2)
nutzungsDauer=models.IntegerField() # years
abschreibungsArt = models.CharField(max_length=255) # linear
# Nutzung pro Umsatzbereich in Prozent + nur zu Gesamtunternehmen zugehörig
'''
# Arbeitsmarkt
'''
Mitarbeiter nach kategorie
Anzahl
Brutto Kosten
Sozialkosten in Summe oder in Prozent
keine Kapazitärsplanung
'''
'''
Kapital
Einlagen und Entnahmen pro Jahr
Fremdkaptial
Einzahlung (Kreditsumme)
Tilgung
Zins
'''
'''
Staat
EtragsSteuern in Prozent vom Gewinn (ca. 30 %)
Subventionen
'''

@ -0,0 +1,16 @@
{{ myform }}
{% for field in myform %}
<div class="form-group">
{% if field.html_name == "user" %}
<input type="hidden" name='user' value="{{user.id}}">
{% else %}
{% if field.html_name == "description" %}
{% else %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{field }}
{% endif %}
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="{{ modelname }}Button" onclick="test()">Submit</button>

@ -1,5 +1,5 @@
<div class="container">
{% load read_dictonary %}
<div class="container">
{% load read_dictonary %}
<!-- <form method="post" class="form-group">-->
{{ description }}
{% for field in myform %}
@ -14,4 +14,4 @@
<button type="submit" class="btn btn-primary" name="{{ modelname }}Button">Submit</button>
<!--</form> -->
</div>
</div>

@ -1,13 +1,14 @@
{% extends 'ugssim/ugssim.html' %}
{% load read_dictonary %}
{% block content %}
<form method="post" class="form-group" action="/planungsparameter/">
{% csrf_token %}
<div class="accordion" id="accordionPlanning">
{% for key,value in formlist.items %}
{% define value|lookup:'form' as myform %}
{% define value|lookup:'modelname' as modelname %}
{% define value|lookup:'description' as description %}
<div class="accordion" id="accordionPlanning">
{% for key,value in formlist.items %}
{% define value|lookup:'form' as myform %}
{% define value|lookup:'modelname' as modelname %}
{% define value|lookup:'description' as description %}
<form name="form{{ modelname }}" method="post" class="form-group" action="/planungsparameter/">
{% csrf_token %}
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
@ -19,22 +20,33 @@
<div id="collapse{{ modelname }}" class="accordion-collapse collapse show"
data-bs-parent="#accordionPlanning">
<div class="accordion-body">
{{ description }}
<p>{{ description }} </p>
<!--
Eventuell kann das noch durch
myform in doppelten geschweiften Klammern ersetzt werden,
aber momentan wird, wenn man das Feld 'user' auf hiddenInput()
in form.py setzt, der value nicht in die HTML Seite geschrieben und
demensprechend nicht beim POST übergeben an Django
-->
{% for field in myform %}
<div class="form-group">
{% if field.html_name == "description" %}
{% else %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{field }}
{% endif %}
</div>
{% if field.html_name == "user" %}
<input type="hidden" name='user' value="{{user.id}}">
{% else %}
{% if field.html_name == "description" %}
{% else %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{field }}
{% endif %}
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="{{ modelname }}Button">Submit</button>
</div>
</div>
</div>
{% endfor %}
</div>
</form>
</div>
</form>
{% endfor %}
{% endblock content %}
</div>

@ -0,0 +1,28 @@
{% extends 'ugssim/ugssim.html' %}
{% load read_dictonary %}
{% block content %}
<form method="post" class="form-group" action="/pp2/">
{% csrf_token %}
<div class="accordion" id="accordionPlanning">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseUserData"
aria-expanded="true" aria-controls="collapseUserData">
Nutzerdaten
</button>
</h2>
</div>
<div id="collapseUserDAta" class="accordion-collapse collapse show"
data-bs-parent="#accordionPlanning">
<div class="accordion-body">
<div class="form-group">
<label> Vorname</label>
</div>
</div>
</div>
</div>
</form>
{% endblock content %}

@ -1,5 +1,6 @@
{% extends 'ugssim/ugssim.html' %}
{% block content %}
{% block content %}
<div class="container">
<form method="post" class="form-group">
{% csrf_token %}

@ -1,5 +1,6 @@
{% load static %}
<div class="clearfix">
<h1>Excellence in Entrepreneurship
<small>{{ user.firstname }}</small>
<img src="{% static 'img/LogoUGS_rgb.png' %}" class="bd-placeholder-img rounded float-end mr-2" height="50" alt="UGS Logo"></h1>
</div>

@ -5,6 +5,17 @@
Wir haben über 25 Jahre Erfahrung in der Gründungsausbildung, Businessplanentwicklung und Gründerberatung.
<br>
Unzählige Menschen haben mit unserer UGS® Software das Gründungswissen erworben.
<br>
{% if user.is_authenticated %}
Hi {{ user.username }}!
<form action="{% url 'logout' %}" method="post">
{% csrf_token %}
<button type="submit">Log Out</button>
</form>
{% else %}
<p>You are not logged in</p>
<a href="{% url 'login' %}">Log In</a>
{% endif %}
<br>
Über 10.000 Gründer und Gründungsberater verwenden UGS® SIM zur Software unterstützten Erstellung
von Businessplänen und Simulation ihrer Gründungsidee in Deutschland, Österreich und der Schweiz.

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

@ -3,7 +3,7 @@
<script src="{% static 'bootstrap/js/bootstrap.bundle.js' %}"></script>
<!DOCTYPE html>
<html lang="de">
<head>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, intial-scale=1.0">
@ -11,7 +11,7 @@
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
</head>
</head>
<body>
@ -20,4 +20,6 @@
{% block content %}
{% endblock %}
</body>
<script type="application/javascript" src="{% static 'main.js' %}" ></script>
</body>
</html>

@ -4,5 +4,6 @@ from . import views
urlpatterns = [
path('', views.index, name='ugs_index'),
path('planungsparameter/', views.planungsparameter, name='ugs_planungsparameter'),
path('save_planungsparameter/', views.save_planungsparameter, name='save_planungsparameter'),
# path('tables/',views.tables, name='ugstables'),
]

@ -1,11 +1,11 @@
import json
import sys
from django.http import HttpResponse
from django.template import loader
from django.shortcuts import render
from django.shortcuts import render, redirect
from .form import *
def get_class(classname):
"""
Retrieve a class object by its name.
@ -30,25 +30,37 @@ def planungsparameter(request):
formclass für das Formular
über diese wird dann iterierter.
"""
"""
Anleitung für Nutzerdatenlogin und anzeigen
https://github.com/OmiDevProjects/show-only-the-data-of-the-user-that-is-logged-in/blob/master/home/views.py
"""
formlist = {}
modellist = ['Address', 'Summary', 'CompanyData']
modellist = ['Address', 'Summary'] #, 'CompanyData']
for modelname in modellist:
modelclass = get_class(modelname)
formclass = get_class(modelname + 'Form')
if request.method == "POST":
if modelname + 'Button' in request.POST:
form = formclass(request.POST)
form.fields.pop('description')
# form.fields.pop('description')
if form.is_valid():
modelclass.objects.update(**form.cleaned_data)
form = formclass(request.POST)
else:
form = formclass()
else:
# initial.update(model_to_dict(modelclass.objects.filter(id=1).first()))
form = formclass()
try:
adressdict = modelclass.objects.filter(user=request.user).values().first()
form = formclass(initial=adressdict)
except Exception as e:
form = formclass()
formpart = {
'modelname': modelname,
'form': form,
'heading': 'Mandatendaten2',
'description': 'Dict Descriptiopn'
'heading': 'Mandatendaten',
'description': 'Dict Description'
}
formlist.update({modelname + "form": formpart})
@ -59,3 +71,40 @@ def planungsparameter(request):
return render(request, 'planungsparameter/planungsparameter.html', context)
def save_planungsparameter(request):
"""
Save the form data for planungsparameter.
:param request: The HTTP request object.
:return: HttpResponse object.
"""
if request.method == "POST":
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
# Load Body
body = json.loads(request.body.decode('utf-8'))
# Form Data
data = body['data']
# Modelname
modelName = body['modelName']
# Get Classes
formclass = get_class(modelName+'Form')
modelclass = get_class(modelName)
form = formclass(data)
# Check User ID
user_id = request.user.id
try:
form_user_id = int(data['user'])
except Exception as ex:
return redirect('logout')
if form_user_id != user_id:
return redirect('logout')
else:
# Update Database
if form.is_valid():
form.save()
modelclass.objects.udpate_or_create(**form.cleaned_data)
return HttpResponse("Form data saved successfully.")
return HttpResponse("Form data NOT saved.")

Loading…
Cancel
Save