separate settings
This commit is contained in:
parent
bfb76658d1
commit
3261c0a96d
11 changed files with 249 additions and 126 deletions
|
@ -37,6 +37,9 @@ app.register_blueprint(vmanager_blueprint)
|
||||||
from .auth import auth as auth_blueprint
|
from .auth import auth as auth_blueprint
|
||||||
app.register_blueprint(auth_blueprint, url_prefix='/auth')
|
app.register_blueprint(auth_blueprint, url_prefix='/auth')
|
||||||
|
|
||||||
|
from .settings import settings as settings_blueprint
|
||||||
|
app.register_blueprint(settings_blueprint, url_prefix='/settings')
|
||||||
|
|
||||||
from .uinvoice import uinvoice as uinvoice_blueprint
|
from .uinvoice import uinvoice as uinvoice_blueprint
|
||||||
app.register_blueprint(uinvoice_blueprint, url_prefix='/uinvoice')
|
app.register_blueprint(uinvoice_blueprint, url_prefix='/uinvoice')
|
||||||
|
|
||||||
|
@ -57,7 +60,7 @@ app.json_encoder = CustomJSONEncoder
|
||||||
if not app.debug:
|
if not app.debug:
|
||||||
import logging
|
import logging
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
file_handler = RotatingFileHandler('/home/proxadmin/appserver/proxadmin/app/log/proxadmin.log', 'a', 1 * 1024 * 1024, 10)
|
file_handler = RotatingFileHandler('/home/proxadmin/appserver/proxadmin/log/proxadmin.log', 'a', 1 * 1024 * 1024, 10)
|
||||||
file_handler.setLevel(logging.INFO)
|
file_handler.setLevel(logging.INFO)
|
||||||
file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
|
file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
|
||||||
app.logger.addHandler(file_handler)
|
app.logger.addHandler(file_handler)
|
||||||
|
|
|
@ -56,6 +56,43 @@ def login():
|
||||||
|
|
||||||
return render_template('auth/login.html', page=page, form=form)
|
return render_template('auth/login.html', page=page, form=form)
|
||||||
|
|
||||||
|
#PROFILE
|
||||||
|
@auth.route('/profile', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def profile():
|
||||||
|
page = { 'title': 'Edit Profile' }
|
||||||
|
|
||||||
|
currentmail = current_user.email
|
||||||
|
ouruser = User.query.filter_by(email=currentmail).first()
|
||||||
|
db.session.commit()
|
||||||
|
wallet = "%.2f" % round(ouruser.wallet, 3)
|
||||||
|
print(wallet)
|
||||||
|
form = EditProfileForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
current_user.name = form.name.data
|
||||||
|
current_user.address = form.address.data
|
||||||
|
current_user.city = form.city.data
|
||||||
|
current_user.postcode = form.postcode.data
|
||||||
|
current_user.country = form.country.data
|
||||||
|
current_user.phone = form.phone.data
|
||||||
|
current_user.org_responsible = form.org_responsible.data
|
||||||
|
current_user.org_bulstat = form.org_bulstat.data
|
||||||
|
current_user.twofactor = form.twofactor.data
|
||||||
|
db.session.add(current_user)
|
||||||
|
db.session.commit()
|
||||||
|
flash('Info Updated!')
|
||||||
|
|
||||||
|
form.twofactor.data = current_user.twofactor
|
||||||
|
form.name.data = current_user.name
|
||||||
|
form.address.data = current_user.address
|
||||||
|
form.city.data = current_user.city
|
||||||
|
form.postcode.data = current_user.postcode
|
||||||
|
form.country.data = current_user.country
|
||||||
|
form.phone.data = current_user.phone
|
||||||
|
form.org_responsible.data = current_user.org_responsible
|
||||||
|
form.org_bulstat.data = current_user.org_bulstat
|
||||||
|
|
||||||
|
return render_template('auth/profile.html', page=page, form=form)
|
||||||
|
|
||||||
@auth.route('/twofactor', methods=['GET', 'POST'])
|
@auth.route('/twofactor', methods=['GET', 'POST'])
|
||||||
def twofactor():
|
def twofactor():
|
||||||
|
|
107
app/models.py
107
app/models.py
|
@ -1,4 +1,3 @@
|
||||||
import hashlib
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
|
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
|
||||||
|
|
||||||
|
@ -9,12 +8,13 @@ from . import db, lm
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
|
import hashlib
|
||||||
|
from decimal import Decimal
|
||||||
|
from datetime import date, time, datetime, timedelta
|
||||||
import json
|
import json
|
||||||
|
from sortedcontainers import SortedDict
|
||||||
import requests
|
import requests
|
||||||
import onetimepass
|
import onetimepass
|
||||||
from datetime import date, datetime, time, timedelta
|
|
||||||
from sortedcontainers import SortedDict
|
|
||||||
|
|
||||||
|
|
||||||
class Permission:
|
class Permission:
|
||||||
DEPLOY = 0x01
|
DEPLOY = 0x01
|
||||||
|
@ -57,6 +57,7 @@ class User(db.Model, UserMixin):
|
||||||
password_hash = db.Column(db.String(128))
|
password_hash = db.Column(db.String(128))
|
||||||
|
|
||||||
confirmed = db.Column(db.Boolean, default=False)
|
confirmed = db.Column(db.Boolean, default=False)
|
||||||
|
active = db.Column(db.Boolean, default=True)
|
||||||
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
|
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||||
last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
|
last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
|
||||||
last_ip = db.Column(db.String(128))
|
last_ip = db.Column(db.String(128))
|
||||||
|
@ -70,15 +71,24 @@ class User(db.Model, UserMixin):
|
||||||
postcode = db.Column(db.String(10))
|
postcode = db.Column(db.String(10))
|
||||||
country = db.Column(db.String(64))
|
country = db.Column(db.String(64))
|
||||||
phone = db.Column(db.String(64))
|
phone = db.Column(db.String(64))
|
||||||
|
org_companyname = db.Column(db.Unicode(64))
|
||||||
|
org_regaddress = db.Column(db.Unicode(128))
|
||||||
org_responsible = db.Column(db.Unicode(128))
|
org_responsible = db.Column(db.Unicode(128))
|
||||||
org_bulstat = db.Column(db.String(16))
|
org_bulstat = db.Column(db.String(16))
|
||||||
|
org_vat = db.Column(db.Boolean, default=False)
|
||||||
|
org_vatnum = db.Column(db.String(16))
|
||||||
|
|
||||||
|
wallet = db.Column(db.Float)
|
||||||
|
credit = db.Column(db.Float)
|
||||||
|
creditlimit = db.Column(db.Float, default=20.0)
|
||||||
|
|
||||||
|
currency = db.Column(db.String(3), default='BGN')
|
||||||
|
language = db.Column(db.String(2), default='BG')
|
||||||
|
|
||||||
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
|
inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic')
|
||||||
inv_contracts = db.relationship('Contract', backref='owner', lazy='dynamic')
|
inv_contracts = db.relationship('Contract', backref='owner', lazy='dynamic')
|
||||||
inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic')
|
inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic')
|
||||||
|
|
||||||
currency = db.Column(db.String(3), default='BGN')
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(User, self).__init__(**kwargs)
|
super(User, self).__init__(**kwargs)
|
||||||
if self.role is None:
|
if self.role is None:
|
||||||
|
@ -271,7 +281,7 @@ class Service(db.Model):
|
||||||
pid = db.Column(db.Integer, primary_key=True) #PK
|
pid = db.Column(db.Integer, primary_key=True) #PK
|
||||||
name = db.Column(db.String(64))
|
name = db.Column(db.String(64))
|
||||||
image = db.Column(db.String(128))
|
image = db.Column(db.String(128))
|
||||||
description = db.Column(db.String(128))
|
description = db.Column(db.Unicode(128))
|
||||||
unitprice = db.Column(db.Float)
|
unitprice = db.Column(db.Float)
|
||||||
enabled = db.Column(db.Boolean)
|
enabled = db.Column(db.Boolean)
|
||||||
|
|
||||||
|
@ -305,17 +315,57 @@ class Service(db.Model):
|
||||||
}
|
}
|
||||||
return services
|
return services
|
||||||
|
|
||||||
class Order(db.Model):
|
#TRANSACTIONS
|
||||||
__tablename__ = 'orders'
|
class Transaction(db.Model):
|
||||||
|
__tablename__ = 'transaction'
|
||||||
pid = db.Column(db.Integer, primary_key=True)
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
|
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
|
||||||
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
||||||
units = db.Column(db.Integer, default=1)
|
|
||||||
unitvalue = db.Column(db.Float)
|
|
||||||
currency = db.Column(db.String, default='BGN')
|
currency = db.Column(db.String, default='BGN')
|
||||||
paid = db.Column(db.Boolean, default=False)
|
|
||||||
|
|
||||||
#class Invoice(db.Model)
|
#PROFORMA INVOICE CLASS
|
||||||
|
class Invoice(db.Model):
|
||||||
|
__tablename__ = 'invoice'
|
||||||
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
|
invoice_number = db.Column(db.Integer, unique=True)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK
|
||||||
|
date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
||||||
|
currency = db.Column(db.String, default='BGN')
|
||||||
|
tax = db.Column(db.Float) #VAT
|
||||||
|
description = db.Column(db.Unicode(255))
|
||||||
|
|
||||||
|
def sub_total(self):
|
||||||
|
items = self.items
|
||||||
|
sub_total = 0
|
||||||
|
for item in items:
|
||||||
|
sub_total += item.total()
|
||||||
|
return sub_total
|
||||||
|
|
||||||
|
def tax_amount(self):
|
||||||
|
if not self.tax:
|
||||||
|
return 0
|
||||||
|
return self.sub_total() * self.tax / 100.0
|
||||||
|
|
||||||
|
def grand_total(self):
|
||||||
|
amount_str = str(self.sub_total() + self.tax_amount())
|
||||||
|
amount = Decimal(amount_str)
|
||||||
|
rounder = Decimal("0.05") # precision for rounding
|
||||||
|
return amount - amount.remainder_near(rounder)
|
||||||
|
|
||||||
|
class InvoiceItem(db.Model):
|
||||||
|
__tablename__ = 'invoice_item'
|
||||||
|
pid = db.Column(db.Integer, primary_key=True)
|
||||||
|
item_number = db.Column(db.Integer)
|
||||||
|
invoice_id = db.Column(db.Integer, db.ForeignKey('invoice.pid')) #FK
|
||||||
|
item_title = db.Column(db.Unicode(255))
|
||||||
|
item_quantity = db.Column(db.Float)
|
||||||
|
item_price = db.Column(db.Float)
|
||||||
|
amount = db.Column(db.Float)
|
||||||
|
|
||||||
|
invoice = db.relationship(Invoice, backref=backref('items', order_by=item_number, cascade="delete"))
|
||||||
|
|
||||||
|
def total(self):
|
||||||
|
return self.item_quantity * self.item_price
|
||||||
|
|
||||||
#INVENTORY CLASSES
|
#INVENTORY CLASSES
|
||||||
class Deployment(db.Model):
|
class Deployment(db.Model):
|
||||||
|
@ -328,35 +378,34 @@ class Deployment(db.Model):
|
||||||
enabled = db.Column(db.Boolean)
|
enabled = db.Column(db.Boolean)
|
||||||
|
|
||||||
machine_id = db.Column(db.BigInteger) #cubeid
|
machine_id = db.Column(db.BigInteger) #cubeid
|
||||||
machine_alias = db.Column(db.String) #dns name for easy managing
|
machine_alias = db.Column(db.String) #dns name
|
||||||
machine_cpu = db.Column(db.Integer)
|
machine_cpu = db.Column(db.Integer)
|
||||||
machine_mem = db.Column(db.Integer)
|
machine_mem = db.Column(db.Integer)
|
||||||
machine_hdd = db.Column(db.Integer)
|
machine_hdd = db.Column(db.Integer)
|
||||||
credit = db.Column(db.Float)
|
|
||||||
|
|
||||||
def charge():
|
def charge():
|
||||||
result = Deployment.query.all()
|
result = Deployment.query.all()
|
||||||
for deploy in result:
|
for deploy in result:
|
||||||
|
if deploy.enabled == True:
|
||||||
managed_user = User.query.get(deploy.user_id)
|
managed_user = User.query.get(deploy.user_id)
|
||||||
db.session.add(deploy)
|
db.session.add(managed_user)
|
||||||
if datetime.utcnow.date() > (deploy.date_expire - timedelta(days=10)):
|
|
||||||
if deploy.credit > 0:
|
|
||||||
print('{} Deployment {} will expire in 10 days at {}. Creating new order...'.format(managed_user.email, deploy.machine_alias, deploy.date_expire))
|
|
||||||
current_product = Product.query.get(int(deploy.product_id))
|
current_product = Product.query.get(int(deploy.product_id))
|
||||||
order = Order(user_id=managed_user.pid, unitvalue=deploy.credit, description='Cloud server {} - {}'.format(current_product.name, deploy.machine_alias))
|
|
||||||
db.session.add(order)
|
|
||||||
deploy.credit = 0
|
|
||||||
deploy.data_expire = datetime.utcnow.date() + timedelta(days=30)
|
|
||||||
else:
|
|
||||||
cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO']
|
cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO']
|
||||||
mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO']
|
mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO']
|
||||||
hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO']
|
hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO']
|
||||||
total = cpu_cost + mem_cost + hdd_cost
|
total = cpu_cost + mem_cost + hdd_cost
|
||||||
if deploy.enabled == True:
|
|
||||||
print('{}> Charging deployment #{} with {} ({} monthly)'.format(managed_user.email, deploy.pid, total))
|
|
||||||
deploy.credit += total
|
|
||||||
|
if managed_user.wallet - managed_user.credit > managed_user.creditlimit:
|
||||||
|
print('{}> Deployment #{} costs {} today. Credit is now {}'.format(managed_user.email, deploy.machine_id, total, managed_user.credit))
|
||||||
|
managed_user.credit += total
|
||||||
|
else:
|
||||||
|
print('{}> Deployment #{} costs {} today. Credit now is {} and its lower than the credit limit {}.'.format(managed_user.email, deploy.machine_id, total, managed_user.credit, managed_user.creditlimit)
|
||||||
|
print('')
|
||||||
|
if datetime.utcnow.date() ==
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return True
|
if deploy.
|
||||||
|
|
||||||
class Contract(db.Model):
|
class Contract(db.Model):
|
||||||
__tablename__ = 'contracts'
|
__tablename__ = 'contracts'
|
||||||
|
@ -367,7 +416,7 @@ class Contract(db.Model):
|
||||||
date_expire = db.Column(db.DateTime)
|
date_expire = db.Column(db.DateTime)
|
||||||
enabled = db.Column(db.Boolean)
|
enabled = db.Column(db.Boolean)
|
||||||
|
|
||||||
description = db.Column(db.String)
|
description = db.Column(db.Unicode)
|
||||||
units = db.Column(db.Integer)
|
units = db.Column(db.Integer)
|
||||||
discount = db.Column(db.Integer) #percent
|
discount = db.Column(db.Integer) #percent
|
||||||
credit = db.Column(db.Float)
|
credit = db.Column(db.Float)
|
||||||
|
|
3
app/settings/__init__.py
Normal file
3
app/settings/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from flask import Blueprint
|
||||||
|
uinvoice = Blueprint('settings', __name__)
|
||||||
|
from . import routes
|
60
app/settings/forms.py
Normal file
60
app/settings/forms.py
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
from iso3166 import countries
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
from ..models import User, Role
|
||||||
|
|
||||||
|
from flask_wtf import FlaskForm, RecaptchaField
|
||||||
|
from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectField, DecimalField
|
||||||
|
from wtforms import validators, ValidationError
|
||||||
|
from wtforms.fields.html5 import EmailField
|
||||||
|
|
||||||
|
class EditProfileForm(FlaskForm):
|
||||||
|
name = StringField('Лице за контакт:', [validators.DataRequired(), validators.Length(3, 60)])
|
||||||
|
address = StringField('Адрес:', [validators.DataRequired(), validators.Length(2, 50)])
|
||||||
|
city = StringField('Град:', [validators.DataRequired(), validators.Length(2,40)])
|
||||||
|
|
||||||
|
postcode = StringField('Пощенски Код:')
|
||||||
|
|
||||||
|
clist = []
|
||||||
|
for c in countries:
|
||||||
|
clist.append((c.alpha2, c.name))
|
||||||
|
country = SelectField('Държава:', choices=clist, default='BG')
|
||||||
|
|
||||||
|
phone = StringField('Телефон:')
|
||||||
|
org_responsible = StringField('Отговорно Лице:')
|
||||||
|
org_bulstat = StringField('БУЛСТАТ:')
|
||||||
|
twofactor = BooleanField('2-factor authentication')
|
||||||
|
submit = SubmitField('Обнови')
|
||||||
|
|
||||||
|
|
||||||
|
class EditProfileAdminForm(FlaskForm):
|
||||||
|
email = StringField('Електроннa поща (логин):', [validators.DataRequired(), validators.Length(1, 64), validators.Email()])
|
||||||
|
confirmed = BooleanField('Активиран')
|
||||||
|
role = SelectField('Роля', coerce=int)
|
||||||
|
|
||||||
|
name = StringField('Лице за контакт:', [validators.DataRequired(), validators.Length(3, 60)])
|
||||||
|
address = StringField('Адрес:', [validators.DataRequired(), validators.Length(2, 50)])
|
||||||
|
city = StringField('Град:', [validators.DataRequired(), validators.Length(2,40)])
|
||||||
|
postcode = DecimalField('Пощенски Код:')
|
||||||
|
|
||||||
|
clist = []
|
||||||
|
for c in countries:
|
||||||
|
clist.append((c.alpha2, c.name))
|
||||||
|
country = SelectField('Държава:', choices=clist)
|
||||||
|
|
||||||
|
phone = DecimalField('Телефон:', [validators.DataRequired()])
|
||||||
|
org_responsible = StringField('Отговорно Лице:')
|
||||||
|
org_bulstat = StringField('БУЛСТАТ:')
|
||||||
|
submit = SubmitField('Обнови')
|
||||||
|
|
||||||
|
def __init__(self, user, *args, **kwargs):
|
||||||
|
super(EditProfileAdminForm, self).__init__(*args, **kwargs)
|
||||||
|
self.role.choices = [(role.pid, role.name)
|
||||||
|
for role in Role.query.order_by(Role.name).all()]
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
def validate_email(self, field):
|
||||||
|
if field.data != self.user.email and User.query.filter_by(email=field.data).first():
|
||||||
|
raise ValidationError('Email-а е вече регистриран.')
|
||||||
|
|
||||||
|
|
51
app/settings/routes.py
Normal file
51
app/settings/routes.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
from flask import render_template, redirect, request, url_for, flash, session, abort, current_app
|
||||||
|
from flask_login import login_required, login_user, logout_user, current_user
|
||||||
|
from sqlalchemy import desc
|
||||||
|
|
||||||
|
from . import settings
|
||||||
|
from .forms import EditProfileForm, EditProfileAdminForm, ChargeForm, PaymentForm
|
||||||
|
|
||||||
|
from ..email import send_email
|
||||||
|
from .. import db
|
||||||
|
from ..models import User, Order
|
||||||
|
|
||||||
|
#PROFILE
|
||||||
|
@settings.route('/profile', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def profile():
|
||||||
|
page = { 'title': 'Edit Profile' }
|
||||||
|
|
||||||
|
currentmail = current_user.email
|
||||||
|
ouruser = User.query.filter_by(email=currentmail).first()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
#wallet = "%.2f" % round(ouruser.wallet, 3)
|
||||||
|
#print(wallet)
|
||||||
|
|
||||||
|
form = EditProfileForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
current_user.name = form.name.data
|
||||||
|
current_user.address = form.address.data
|
||||||
|
current_user.city = form.city.data
|
||||||
|
current_user.postcode = form.postcode.data
|
||||||
|
current_user.country = form.country.data
|
||||||
|
current_user.phone = form.phone.data
|
||||||
|
current_user.org_responsible = form.org_responsible.data
|
||||||
|
current_user.org_bulstat = form.org_bulstat.data
|
||||||
|
current_user.twofactor = form.twofactor.data
|
||||||
|
db.session.add(current_user)
|
||||||
|
db.session.commit()
|
||||||
|
flash('Info Updated!')
|
||||||
|
|
||||||
|
form.twofactor.data = current_user.twofactor
|
||||||
|
form.name.data = current_user.name
|
||||||
|
form.address.data = current_user.address
|
||||||
|
form.city.data = current_user.city
|
||||||
|
form.postcode.data = current_user.postcode
|
||||||
|
form.country.data = current_user.country
|
||||||
|
form.phone.data = current_user.phone
|
||||||
|
form.org_responsible.data = current_user.org_responsible
|
||||||
|
form.org_bulstat.data = current_user.org_bulstat
|
||||||
|
|
||||||
|
return render_template('settings/profile.html', page=page, form=form)
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<li><a href="{{ url_for('vmanager.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
|
<li><a href="{{ url_for('vmanager.dashboard') }}"><span class="glyphicon glyphicon-eye-open"></span> Dashboard</a></li>
|
||||||
<li><a href="{{ url_for('uinvoice.documents') }}"><span class="glyphicon glyphicon-list-alt"></span> Orders</a></li>
|
<li><a href="{{ url_for('uinvoice.documents') }}"><span class="glyphicon glyphicon-list-alt"></span> Orders</a></li>
|
||||||
<li role="separator" class="divider"></li>
|
<li role="separator" class="divider"></li>
|
||||||
<li><a href="{{ url_for('uinvoice.profile') }}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
|
<li><a href="{{ url_for('settings.profile') }}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
|
||||||
<li><a href="{{ url_for('auth.logout') }}"><span class="glyphicon glyphicon-off"></span> Logout</a></li>
|
<li><a href="{{ url_for('auth.logout') }}"><span class="glyphicon glyphicon-off"></span> Logout</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
10
app/templates/settings/_sidebar.html
Normal file
10
app/templates/settings/_sidebar.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="panel panel-info">
|
||||||
|
<div class="panel-heading">{{ current_user.name }}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<a href="https://en.gravatar.com/site/signup/"><img class="roundavatar" src="{{ current_user.gravatar(128) }}"></img></a><br />
|
||||||
|
2-Factor: {{ current_user.twofactor }}<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% include "uinvoice/_sidebar.html" %}
|
{% include "settings/_sidebar.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">Данни на профила</div>
|
<div class="panel-heading">Данни на профила</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form method="POST" action="{{ url_for('uinvoice.profile') }}">
|
<form method="POST" action="{{ url_for('settings.profile') }}">
|
||||||
<p>
|
<p>
|
||||||
{{ form.name.label }}<br />{{ form.name(size=42) }}<br />
|
{{ form.name.label }}<br />{{ form.name(size=42) }}<br />
|
||||||
{% for error in form.name.errors %}
|
{% for error in form.name.errors %}
|
|
@ -1,4 +1,3 @@
|
||||||
from iso3166 import countries
|
|
||||||
import string
|
import string
|
||||||
import random
|
import random
|
||||||
from ..models import User, Role
|
from ..models import User, Role
|
||||||
|
@ -8,55 +7,6 @@ from wtforms import StringField, PasswordField, BooleanField, SubmitField, Selec
|
||||||
from wtforms import validators, ValidationError
|
from wtforms import validators, ValidationError
|
||||||
from wtforms.fields.html5 import EmailField
|
from wtforms.fields.html5 import EmailField
|
||||||
|
|
||||||
class EditProfileForm(FlaskForm):
|
|
||||||
name = StringField('Лице за контакт:', [validators.DataRequired(), validators.Length(3, 60)])
|
|
||||||
address = StringField('Адрес:', [validators.DataRequired(), validators.Length(2, 50)])
|
|
||||||
city = StringField('Град:', [validators.DataRequired(), validators.Length(2,40)])
|
|
||||||
|
|
||||||
postcode = StringField('Пощенски Код:')
|
|
||||||
|
|
||||||
clist = []
|
|
||||||
for c in countries:
|
|
||||||
clist.append((c.alpha2, c.name))
|
|
||||||
country = SelectField('Държава:', choices=clist, default='BG')
|
|
||||||
|
|
||||||
phone = StringField('Телефон:')
|
|
||||||
org_responsible = StringField('Отговорно Лице:')
|
|
||||||
org_bulstat = StringField('БУЛСТАТ:')
|
|
||||||
twofactor = BooleanField('2-factor authentication')
|
|
||||||
submit = SubmitField('Обнови')
|
|
||||||
|
|
||||||
|
|
||||||
class EditProfileAdminForm(FlaskForm):
|
|
||||||
email = StringField('Електроннa поща (логин):', [validators.DataRequired(), validators.Length(1, 64), validators.Email()])
|
|
||||||
confirmed = BooleanField('Активиран')
|
|
||||||
role = SelectField('Роля', coerce=int)
|
|
||||||
|
|
||||||
name = StringField('Лице за контакт:', [validators.DataRequired(), validators.Length(3, 60)])
|
|
||||||
address = StringField('Адрес:', [validators.DataRequired(), validators.Length(2, 50)])
|
|
||||||
city = StringField('Град:', [validators.DataRequired(), validators.Length(2,40)])
|
|
||||||
postcode = DecimalField('Пощенски Код:')
|
|
||||||
|
|
||||||
clist = []
|
|
||||||
for c in countries:
|
|
||||||
clist.append((c.alpha2, c.name))
|
|
||||||
country = SelectField('Държава:', choices=clist)
|
|
||||||
|
|
||||||
phone = DecimalField('Телефон:', [validators.DataRequired()])
|
|
||||||
org_responsible = StringField('Отговорно Лице:')
|
|
||||||
org_bulstat = StringField('БУЛСТАТ:')
|
|
||||||
submit = SubmitField('Обнови')
|
|
||||||
|
|
||||||
def __init__(self, user, *args, **kwargs):
|
|
||||||
super(EditProfileAdminForm, self).__init__(*args, **kwargs)
|
|
||||||
self.role.choices = [(role.pid, role.name)
|
|
||||||
for role in Role.query.order_by(Role.name).all()]
|
|
||||||
self.user = user
|
|
||||||
|
|
||||||
def validate_email(self, field):
|
|
||||||
if field.data != self.user.email and User.query.filter_by(email=field.data).first():
|
|
||||||
raise ValidationError('Email-а е вече регистриран.')
|
|
||||||
|
|
||||||
class ChargeForm(FlaskForm):
|
class ChargeForm(FlaskForm):
|
||||||
invoice_amount = DecimalField('Стойност:', [validators.DataRequired(), validators.NumberRange(min=0, max=6)])
|
invoice_amount = DecimalField('Стойност:', [validators.DataRequired(), validators.NumberRange(min=0, max=6)])
|
||||||
submit = SubmitField('Зареди')
|
submit = SubmitField('Зареди')
|
||||||
|
|
|
@ -9,46 +9,6 @@ from ..email import send_email
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..models import User, Order
|
from ..models import User, Order
|
||||||
|
|
||||||
#PROFILE
|
|
||||||
@uinvoice.route('/profile', methods=['GET', 'POST'])
|
|
||||||
@login_required
|
|
||||||
def profile():
|
|
||||||
page = { 'title': 'Edit Profile' }
|
|
||||||
|
|
||||||
currentmail = current_user.email
|
|
||||||
ouruser = User.query.filter_by(email=currentmail).first()
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
#wallet = "%.2f" % round(ouruser.wallet, 3)
|
|
||||||
#print(wallet)
|
|
||||||
|
|
||||||
form = EditProfileForm()
|
|
||||||
if form.validate_on_submit():
|
|
||||||
current_user.name = form.name.data
|
|
||||||
current_user.address = form.address.data
|
|
||||||
current_user.city = form.city.data
|
|
||||||
current_user.postcode = form.postcode.data
|
|
||||||
current_user.country = form.country.data
|
|
||||||
current_user.phone = form.phone.data
|
|
||||||
current_user.org_responsible = form.org_responsible.data
|
|
||||||
current_user.org_bulstat = form.org_bulstat.data
|
|
||||||
current_user.twofactor = form.twofactor.data
|
|
||||||
db.session.add(current_user)
|
|
||||||
db.session.commit()
|
|
||||||
flash('Info Updated!')
|
|
||||||
|
|
||||||
form.twofactor.data = current_user.twofactor
|
|
||||||
form.name.data = current_user.name
|
|
||||||
form.address.data = current_user.address
|
|
||||||
form.city.data = current_user.city
|
|
||||||
form.postcode.data = current_user.postcode
|
|
||||||
form.country.data = current_user.country
|
|
||||||
form.phone.data = current_user.phone
|
|
||||||
form.org_responsible.data = current_user.org_responsible
|
|
||||||
form.org_bulstat.data = current_user.org_bulstat
|
|
||||||
|
|
||||||
return render_template('uinvoice/profile.html', page=page, form=form)
|
|
||||||
|
|
||||||
#INVOICES
|
#INVOICES
|
||||||
#@uinvoice.route('/charge', methods=['GET', 'POST'])
|
#@uinvoice.route('/charge', methods=['GET', 'POST'])
|
||||||
#@login_required
|
#@login_required
|
||||||
|
|
Loading…
Reference in a new issue