treewide: fix a bunch of lints
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
from typing import Any
|
||||
from pathlib import Path
|
||||
import tomllib
|
||||
import os
|
||||
import sys
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
DEFAULT_CONFIG_PATH = Path("/etc/dibbler/dibbler.toml")
|
||||
|
||||
@@ -19,11 +19,11 @@ def default_config_path_submissive_and_readable() -> bool:
|
||||
and DEFAULT_CONFIG_PATH.stat().st_gid == os.getgid()
|
||||
),
|
||||
(DEFAULT_CONFIG_PATH.stat().st_mode & 0o004),
|
||||
]
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
config: dict[str, dict[str, Any]] = dict()
|
||||
config: dict[str, dict[str, Any]] = {}
|
||||
|
||||
|
||||
def load_config(config_path: Path | None = None):
|
||||
@@ -49,7 +49,7 @@ def config_db_string() -> str:
|
||||
path = Path(config["database"]["sqlite"]["path"])
|
||||
return f"sqlite:///{path.absolute()}"
|
||||
|
||||
elif db_type == "postgresql":
|
||||
if db_type == "postgresql":
|
||||
host = config["database"]["postgresql"]["host"]
|
||||
port = config["database"]["postgresql"].get("port", 5432)
|
||||
username = config["database"]["postgresql"].get("username", "dibbler")
|
||||
@@ -65,8 +65,6 @@ def config_db_string() -> str:
|
||||
|
||||
if host.startswith("/"):
|
||||
return f"postgresql+psycopg2://{username}:{password}@/{dbname}?host={host}"
|
||||
else:
|
||||
return f"postgresql+psycopg2://{username}:{password}@{host}:{port}/{dbname}"
|
||||
else:
|
||||
print(f"Error: unknown database type '{db_type}'")
|
||||
exit(1)
|
||||
return f"postgresql+psycopg2://{username}:{password}@{host}:{port}/{dbname}"
|
||||
print(f"Error: unknown database type '{db_type}'")
|
||||
exit(1)
|
||||
|
||||
@@ -2,7 +2,8 @@ import os
|
||||
import pwd
|
||||
import signal
|
||||
import subprocess
|
||||
from typing import Any, Callable, Literal
|
||||
from collections.abc import Callable
|
||||
from typing import Any, Literal
|
||||
|
||||
from sqlalchemy import and_, not_, or_
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -24,18 +25,17 @@ def search_user(
|
||||
)
|
||||
if exact_match:
|
||||
return exact_match
|
||||
user_list = (
|
||||
return (
|
||||
sql_session.query(User)
|
||||
.filter(
|
||||
or_(
|
||||
User.name.ilike(f"%{string}%"),
|
||||
User.card.ilike(f"%{string}%"),
|
||||
User.rfid.ilike(f"%{string}%"),
|
||||
)
|
||||
),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return user_list
|
||||
|
||||
|
||||
def search_product(
|
||||
@@ -60,7 +60,7 @@ def search_product(
|
||||
Product.name == string,
|
||||
not_(Product.hidden),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
.first()
|
||||
)
|
||||
@@ -73,7 +73,7 @@ def search_product(
|
||||
or_(
|
||||
Product.bar_code.ilike(f"%{string}%"),
|
||||
Product.name.ilike(f"%{string}%"),
|
||||
)
|
||||
),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
@@ -87,7 +87,7 @@ def search_product(
|
||||
Product.name.ilike(f"%{string}%"),
|
||||
not_(Product.hidden),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
@@ -121,7 +121,7 @@ def guess_data_type(string: str) -> Literal["card", "rfid", "bar_code", "usernam
|
||||
|
||||
def argmax(
|
||||
d,
|
||||
all: bool = False,
|
||||
all_: bool = False,
|
||||
value: Callable[[Any], Any] | None = None,
|
||||
):
|
||||
maxarg = None
|
||||
@@ -133,7 +133,7 @@ def argmax(
|
||||
for key in list(d.keys()):
|
||||
if maxarg is None or d[key] > d[maxarg]:
|
||||
maxarg = key
|
||||
if all:
|
||||
if all_:
|
||||
return [k for k in list(d.keys()) if d[k] == d[maxarg]]
|
||||
return maxarg
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import os
|
||||
import datetime
|
||||
|
||||
# import barcode
|
||||
# from brother_ql.brother_ql_create import create_label
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
import datetime
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .helpers import *
|
||||
from ..models import Transaction
|
||||
from .helpers import *
|
||||
|
||||
|
||||
def getUser(sql_session: Session):
|
||||
@@ -176,7 +177,7 @@ def addLineToDatabase(database, inputLine):
|
||||
if abs(inputLine.price) > 90000:
|
||||
return database
|
||||
# fyller inn for varer
|
||||
if (not inputLine.product == "") and (
|
||||
if (inputLine.product != "") and (
|
||||
(inputLine.inputProduct == "") or (inputLine.inputProduct == inputLine.product)
|
||||
):
|
||||
database.varePersonAntall[inputLine.product][inputLine.user] = (
|
||||
@@ -190,7 +191,7 @@ def addLineToDatabase(database, inputLine):
|
||||
database.vareUkedagAntall[inputLine.product][inputLine.weekday] += 1
|
||||
# fyller inn for personer
|
||||
if (inputLine.inputUser == "") or (inputLine.inputUser == inputLine.user):
|
||||
if not inputLine.product == "":
|
||||
if inputLine.product != "":
|
||||
database.personVareAntall[inputLine.user][inputLine.product] = (
|
||||
database.personVareAntall[inputLine.user].setdefault(inputLine.product, 0) + 1
|
||||
)
|
||||
@@ -214,7 +215,7 @@ def addLineToDatabase(database, inputLine):
|
||||
database.personNegTransactions[inputLine.user] = (
|
||||
database.personNegTransactions.setdefault(inputLine.user, 0) + inputLine.price
|
||||
)
|
||||
elif not (inputLine.inputType == 1):
|
||||
elif inputLine.inputType != 1:
|
||||
database.globalVareAntall[inputLine.product] = (
|
||||
database.globalVareAntall.setdefault(inputLine.product, 0) + 1
|
||||
)
|
||||
@@ -225,7 +226,7 @@ def addLineToDatabase(database, inputLine):
|
||||
# fyller inn for global statistikk
|
||||
if (inputLine.inputType == 3) or (inputLine.inputType == 4):
|
||||
database.pengebeholdning[inputLine.dateNum] += inputLine.price
|
||||
if not (inputLine.product == ""):
|
||||
if inputLine.product != "":
|
||||
database.globalPersonAntall[inputLine.user] = (
|
||||
database.globalPersonAntall.setdefault(inputLine.user, 0) + 1
|
||||
)
|
||||
@@ -273,7 +274,7 @@ def buildDatabaseFromDb(inputType, inputProduct, inputUser, sql_session: Session
|
||||
inputLine.price = 0
|
||||
|
||||
print("saving as default.dibblerlog...", end=" ")
|
||||
f = open("default.dibblerlog", "w")
|
||||
f = Path.open("default.dibblerlog", "w")
|
||||
line_format = "%s|%s|%s|%s|%s|%s\n"
|
||||
transaction_list = sql_session.query(Transaction).all()
|
||||
for transaction in transaction_list:
|
||||
@@ -290,7 +291,7 @@ def buildDatabaseFromDb(inputType, inputProduct, inputUser, sql_session: Session
|
||||
transaction.description,
|
||||
)
|
||||
f.write(line.encode("utf8"))
|
||||
f.close
|
||||
f.close()
|
||||
# bygg database.pengebeholdning
|
||||
if (inputType == 3) or (inputType == 4):
|
||||
for i in range(inputLine.numberOfDays + 1):
|
||||
@@ -310,7 +311,7 @@ def buildDatabaseFromFile(inputFile, inputType, inputProduct, inputUser):
|
||||
sdate = input("enter start date (yyyy-mm-dd)? ")
|
||||
edate = input("enter end date (yyyy-mm-dd)? ")
|
||||
|
||||
f = open(inputFile)
|
||||
f = Path.open(inputFile)
|
||||
try:
|
||||
fileLines = f.readlines()
|
||||
finally:
|
||||
@@ -328,7 +329,7 @@ def buildDatabaseFromFile(inputFile, inputType, inputProduct, inputUser):
|
||||
database.globalUkedagForbruk = [0] * 7
|
||||
database.pengebeholdning = [0] * (inputLine.numberOfDays + 1)
|
||||
for linje in fileLines:
|
||||
if not (linje[0] == "#") and not (linje == "\n"):
|
||||
if linje[0] != "#" and linje != "\n":
|
||||
# henter dateNum, products, user, price
|
||||
restDel = linje.partition("|")
|
||||
restDel = restDel[2].partition(" ")
|
||||
@@ -406,7 +407,7 @@ def printWeekdays(week, days):
|
||||
def printBalance(database, user):
|
||||
forbruk = 0
|
||||
if user in database.personVareVerdi:
|
||||
forbruk = sum([i for i in list(database.personVareVerdi[user].values())])
|
||||
forbruk = sum(list(database.personVareVerdi[user].values()))
|
||||
print("totalt kjøpt for: ", forbruk, end=" ")
|
||||
if user in database.personNegTransactions:
|
||||
print("kr, totalt lagt til: ", -database.personNegTransactions[user], end=" ")
|
||||
@@ -453,9 +454,9 @@ def printGlobal(database, dateLine, n):
|
||||
"Det er solgt varer til en verdi av: ",
|
||||
sum(database.globalDatoForbruk),
|
||||
"kr, det er lagt til",
|
||||
-sum([i for i in list(database.personNegTransactions.values())]),
|
||||
-sum(list(database.personNegTransactions.values())),
|
||||
"og tatt fra",
|
||||
sum([i for i in list(database.personPosTransactions.values())]),
|
||||
sum(list(database.personPosTransactions.values())),
|
||||
end=" ",
|
||||
)
|
||||
print(
|
||||
@@ -470,12 +471,12 @@ def alt4menuTextOnly(database, dateLine, sql_session: Session):
|
||||
n = 10
|
||||
while 1:
|
||||
print(
|
||||
"\n1: user-statistics, 2: product-statistics, 3:global-statistics, n: adjust amount of data shown q:quit"
|
||||
"\n1: user-statistics, 2: product-statistics, 3:global-statistics, n: adjust amount of data shown q:quit",
|
||||
)
|
||||
inp = input("")
|
||||
if inp == "q":
|
||||
break
|
||||
elif inp == "1":
|
||||
if inp == "1":
|
||||
try:
|
||||
printUser(database, dateLine, getUser(sql_session), n)
|
||||
except:
|
||||
@@ -505,5 +506,5 @@ def statisticsTextOnly(sql_session: Session):
|
||||
database, dateLine = buildDatabaseFromDb(inputType, product, user, sql_session)
|
||||
elif inp == "0" or inp == "":
|
||||
database, dateLine = buildDatabaseFromFile("default.dibblerlog", inputType, product, user)
|
||||
if not inp == "q":
|
||||
if inp != "q":
|
||||
alt4menuTextOnly(database, dateLine, sql_session)
|
||||
|
||||
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dibbler.conf import load_config, config_db_string
|
||||
from dibbler.conf import config_db_string, load_config
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
|
||||
@@ -26,28 +26,28 @@ __all__ = [
|
||||
from .addstock import AddStockMenu
|
||||
from .buymenu import BuyMenu
|
||||
from .editing import (
|
||||
AddUserMenu,
|
||||
EditUserMenu,
|
||||
AddProductMenu,
|
||||
EditProductMenu,
|
||||
AddUserMenu,
|
||||
AdjustStockMenu,
|
||||
CleanupStockMenu,
|
||||
EditProductMenu,
|
||||
EditUserMenu,
|
||||
)
|
||||
from .faq import FAQMenu
|
||||
from .helpermenus import Menu
|
||||
from .mainmenu import MainMenu
|
||||
from .miscmenus import (
|
||||
ProductSearchMenu,
|
||||
TransferMenu,
|
||||
AdjustCreditMenu,
|
||||
UserListMenu,
|
||||
ShowUserMenu,
|
||||
ProductListMenu,
|
||||
ProductSearchMenu,
|
||||
ShowUserMenu,
|
||||
TransferMenu,
|
||||
UserListMenu,
|
||||
)
|
||||
from .printermenu import PrintLabelMenu
|
||||
from .stats import (
|
||||
ProductPopularityMenu,
|
||||
ProductRevenueMenu,
|
||||
BalanceMenu,
|
||||
LoggedStatisticsMenu,
|
||||
ProductPopularityMenu,
|
||||
ProductRevenueMenu,
|
||||
)
|
||||
|
||||
@@ -139,10 +139,10 @@ much money you're due in credits for the purchase when prompted.\n"""
|
||||
old_price = product.price
|
||||
old_hidden = product.hidden
|
||||
product.price = int(
|
||||
ceil(float(value) / (max(product.stock, 0) + self.products[product][0]))
|
||||
ceil(float(value) / (max(product.stock, 0) + self.products[product][0])),
|
||||
)
|
||||
product.stock = max(
|
||||
self.products[product][0], product.stock + self.products[product][0]
|
||||
self.products[product][0], product.stock + self.products[product][0],
|
||||
)
|
||||
product.hidden = False
|
||||
print(
|
||||
|
||||
@@ -64,7 +64,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
print("***********************************************************************")
|
||||
print("")
|
||||
print(
|
||||
f"USER {user.name} HAS LOWER CREDIT THAN {config['limits']['low_credit_warning_limit']:d}."
|
||||
f"USER {user.name} HAS LOWER CREDIT THAN {config['limits']['low_credit_warning_limit']:d}.",
|
||||
)
|
||||
print("THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH.")
|
||||
print("CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS.")
|
||||
@@ -74,8 +74,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
if timeout:
|
||||
print("THIS PURCHASE WILL AUTOMATICALLY BE PERFORMED IN 3 MINUTES!")
|
||||
return self.confirm(prompt=">", default=True, timeout=180)
|
||||
else:
|
||||
return self.confirm(prompt=">", default=True)
|
||||
return self.confirm(prompt=">", default=True)
|
||||
|
||||
def add_thing_to_purchase(
|
||||
self,
|
||||
@@ -145,7 +144,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
True,
|
||||
True,
|
||||
): "Enter more products or users, or an empty line to confirm",
|
||||
}[(len(self.purchase.transactions) > 0, len(self.purchase.entries) > 0)]
|
||||
}[(len(self.purchase.transactions) > 0, len(self.purchase.entries) > 0)],
|
||||
)
|
||||
|
||||
# Read in a 'thing' (product or user):
|
||||
@@ -163,16 +162,15 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
if thing is None:
|
||||
if not self.complete_input():
|
||||
if self.confirm(
|
||||
"Not enough information entered. Abort purchase?", default=True
|
||||
"Not enough information entered. Abort purchase?", default=True,
|
||||
):
|
||||
return False
|
||||
continue
|
||||
break
|
||||
else:
|
||||
# once we get something in the
|
||||
# purchase, we want to protect the
|
||||
# user from accidentally killing it
|
||||
self.exit_confirm_msg = "Abort purchase?"
|
||||
# once we get something in the
|
||||
# purchase, we want to protect the
|
||||
# user from accidentally killing it
|
||||
self.exit_confirm_msg = "Abort purchase?"
|
||||
|
||||
# Add the thing to our purchase object:
|
||||
if not self.add_thing_to_purchase(thing, amount=num):
|
||||
@@ -221,7 +219,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
string += "(empty)"
|
||||
else:
|
||||
string += ", ".join(
|
||||
[t.user.name + ("*" if not self.credit_check(t.user) else "") for t in transactions]
|
||||
[t.user.name + ("*" if not self.credit_check(t.user) else "") for t in transactions],
|
||||
)
|
||||
string += "\n products: "
|
||||
if len(entries) == 0:
|
||||
@@ -229,7 +227,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
||||
else:
|
||||
string += "\n "
|
||||
string += "\n ".join(
|
||||
[f"{e.amount:d}x {e.product.name} ({e.product.price:d} kr)" for e in entries]
|
||||
[f"{e.amount:d}x {e.product.name} ({e.product.price:d} kr)" for e in entries],
|
||||
)
|
||||
if len(transactions) > 1:
|
||||
string += f"\n price per person: {self.purchase.price_per_transaction():d} kr"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import sqlalchemy
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dibbler.models import User, Product
|
||||
from dibbler.models import Product, User
|
||||
|
||||
from .helpermenus import Menu, Selector
|
||||
|
||||
__all__ = [
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .helpermenus import Menu, MessageMenu
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Callable, Iterable
|
||||
from select import select
|
||||
from typing import Any, Callable, Iterable, Literal, Self
|
||||
from typing import Any, Literal, Self
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -24,7 +24,7 @@ class ExitMenuException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Menu(object):
|
||||
class Menu:
|
||||
name: str
|
||||
sql_session: Session
|
||||
items: list[Self | tuple | str]
|
||||
@@ -111,10 +111,9 @@ class Menu(object):
|
||||
def item_name(self, i: int) -> str:
|
||||
if self.item_is_submenu(i):
|
||||
return self.items[i].name
|
||||
elif isinstance(self.items[i], tuple):
|
||||
if isinstance(self.items[i], tuple):
|
||||
return self.items[i][1]
|
||||
else:
|
||||
return self.items[i]
|
||||
return self.items[i]
|
||||
|
||||
def item_value(self, i: int):
|
||||
if isinstance(self.items[i], tuple):
|
||||
@@ -189,7 +188,7 @@ class Menu(object):
|
||||
):
|
||||
if length_range[0] and length_range[1]:
|
||||
print(
|
||||
f"Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]"
|
||||
f"Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]",
|
||||
)
|
||||
elif length_range[0]:
|
||||
print(f"Value must have length at least {length_range[0]:d}")
|
||||
@@ -231,7 +230,7 @@ class Menu(object):
|
||||
else:
|
||||
if result.isdigit():
|
||||
choice = int(result)
|
||||
if choice == 0 and 10 <= number_of_choices:
|
||||
if choice == 0 and number_of_choices >= 10:
|
||||
return 10
|
||||
if 0 < choice <= number_of_choices:
|
||||
return choice
|
||||
@@ -342,29 +341,28 @@ class Menu(object):
|
||||
search_lst = search_str.split(" ")
|
||||
if search_str == "" and empty_input_permitted:
|
||||
return None
|
||||
else:
|
||||
result = self.search_for_thing(
|
||||
search_str,
|
||||
permitted_things,
|
||||
add_nonexisting,
|
||||
find_hidden_products,
|
||||
)
|
||||
num = 1
|
||||
result = self.search_for_thing(
|
||||
search_str,
|
||||
permitted_things,
|
||||
add_nonexisting,
|
||||
find_hidden_products,
|
||||
)
|
||||
num = 1
|
||||
|
||||
if (result is None) and (len(search_lst) > 1):
|
||||
print('Interpreting input as "<number> <product>"')
|
||||
try:
|
||||
num = int(search_lst[0])
|
||||
result = self.search_for_thing(
|
||||
" ".join(search_lst[1:]),
|
||||
permitted_things,
|
||||
add_nonexisting,
|
||||
find_hidden_products,
|
||||
)
|
||||
# Her kan det legges inn en except ValueError,
|
||||
# men da blir det fort mye plaging av brukeren
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if (result is None) and (len(search_lst) > 1):
|
||||
print('Interpreting input as "<number> <product>"')
|
||||
try:
|
||||
num = int(search_lst[0])
|
||||
result = self.search_for_thing(
|
||||
" ".join(search_lst[1:]),
|
||||
permitted_things,
|
||||
add_nonexisting,
|
||||
find_hidden_products,
|
||||
)
|
||||
# Her kan det legges inn en except ValueError,
|
||||
# men da blir det fort mye plaging av brukeren
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return result, num
|
||||
|
||||
def search_for_thing(
|
||||
@@ -544,7 +542,7 @@ class Menu(object):
|
||||
of money PVVVV owes the user. This value decreases with the
|
||||
appropriate amount when you register a purchase, and you may increase
|
||||
it by putting money in the box and using the "Adjust credit" menu.
|
||||
"""
|
||||
""",
|
||||
)
|
||||
|
||||
def local_help(self):
|
||||
@@ -627,17 +625,16 @@ class ConfirmMenu(Menu):
|
||||
options = {True: "[y]/n", False: "y/[n]", None: "y/n"}[self.default]
|
||||
while True:
|
||||
result = self.input_str(
|
||||
f"{self.prompt} ({options})", end_prompt=": ", timeout=self.timeout
|
||||
f"{self.prompt} ({options})", end_prompt=": ", timeout=self.timeout,
|
||||
)
|
||||
result = result.lower().strip()
|
||||
if result in ["y", "yes"]:
|
||||
return True
|
||||
elif result in ["n", "no"]:
|
||||
if result in ["n", "no"]:
|
||||
return False
|
||||
elif self.default is not None and result == "":
|
||||
if self.default is not None and result == "":
|
||||
return self.default
|
||||
else:
|
||||
print("Please answer yes or no")
|
||||
print("Please answer yes or no")
|
||||
|
||||
|
||||
class Selector(Menu):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
@@ -48,18 +47,18 @@ class MainMenu(Menu):
|
||||
restart()
|
||||
pass
|
||||
return True
|
||||
elif result == "c":
|
||||
if result == "c":
|
||||
os.system(
|
||||
'echo -e "\033['
|
||||
+ str(random.randint(40, 49))
|
||||
+ ";"
|
||||
+ str(random.randint(30, 37))
|
||||
+ ';5m"'
|
||||
+ ';5m"',
|
||||
)
|
||||
os.system("clear")
|
||||
self.show_context()
|
||||
return True
|
||||
elif result == "cs":
|
||||
if result == "cs":
|
||||
os.system('echo -e "\033[0m"')
|
||||
os.system("clear")
|
||||
self.show_context()
|
||||
|
||||
@@ -2,8 +2,8 @@ import sqlalchemy
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dibbler.conf import config
|
||||
from dibbler.models import Transaction, Product, User
|
||||
from dibbler.lib.helpers import less
|
||||
from dibbler.models import Product, Transaction, User
|
||||
|
||||
from .helpermenus import Menu, Selector
|
||||
|
||||
@@ -90,10 +90,7 @@ class ShowUserMenu(Menu):
|
||||
if t.purchase:
|
||||
products = []
|
||||
for entry in t.purchase.entries:
|
||||
if abs(entry.amount) != 1:
|
||||
amount = f"{abs(entry.amount)}x "
|
||||
else:
|
||||
amount = ""
|
||||
amount = f"{abs(entry.amount)}x " if abs(entry.amount) != 1 else ""
|
||||
product = f"{amount}{entry.product.name}"
|
||||
products.append(product)
|
||||
string += "purchase ("
|
||||
@@ -215,14 +212,11 @@ class ProductSearchMenu(Menu):
|
||||
self.print_header()
|
||||
self.set_context("Enter (part of) product name or bar code")
|
||||
product = self.input_product()
|
||||
print(
|
||||
"Result: %s, price: %d kr, bar code: %s, stock: %d, hidden: %s"
|
||||
% (
|
||||
product.name,
|
||||
product.price,
|
||||
product.bar_code,
|
||||
product.stock,
|
||||
("Y" if product.hidden else "N"),
|
||||
)
|
||||
)
|
||||
print(", ".join([
|
||||
f"Result: {product.name}",
|
||||
f"price: {product.price} kr",
|
||||
f"bar code: {product.bar_code}",
|
||||
f"stock: {product.stock}",
|
||||
f"hidden: {'Y' if product.hidden else 'N'}",
|
||||
]))
|
||||
# self.pause()
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import re
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dibbler.conf import config
|
||||
from dibbler.models import Product, User
|
||||
# from dibbler.lib.printer_helpers import print_bar_code, print_name_label
|
||||
|
||||
from .helpermenus import Menu
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ from sqlalchemy import desc, func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from dibbler.lib.helpers import less
|
||||
from dibbler.models import PurchaseEntry, Product, User
|
||||
from dibbler.lib.statistikkHelpers import statisticsTextOnly
|
||||
from dibbler.models import Product, PurchaseEntry, User
|
||||
|
||||
from .helpermenus import Menu
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class Base(DeclarativeBase):
|
||||
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
|
||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||
"pk": "pk_%(table_name)s",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@declared_attr.directive
|
||||
@@ -38,7 +38,7 @@ class Base(DeclarativeBase):
|
||||
isinstance(v, InstrumentedList),
|
||||
isinstance(v, InstrumentedSet),
|
||||
isinstance(v, InstrumentedDict),
|
||||
]
|
||||
],
|
||||
)
|
||||
)
|
||||
return f"<{self.__class__.__name__}({columns})>"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import (
|
||||
|
||||
@@ -43,8 +43,7 @@ class Purchase(Base):
|
||||
def price_per_transaction(self, round_up: bool = True) -> int:
|
||||
if round_up:
|
||||
return int(math.ceil(float(self.price) / len(self.transactions)))
|
||||
else:
|
||||
return int(math.floor(float(self.price) / len(self.transactions)))
|
||||
return int(math.floor(float(self.price) / len(self.transactions)))
|
||||
|
||||
def set_price(self, round_up: bool = True) -> None:
|
||||
self.price = 0
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import (
|
||||
Integer,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
)
|
||||
from sqlalchemy.orm import (
|
||||
Mapped,
|
||||
@@ -27,8 +28,8 @@ class PurchaseEntry(Base):
|
||||
product_id: Mapped[int] = mapped_column(ForeignKey("products.product_id"))
|
||||
purchase_id: Mapped[int] = mapped_column(ForeignKey("purchases.id"))
|
||||
|
||||
product: Mapped[Product] = relationship(back_populates='purchases', lazy="joined")
|
||||
purchase: Mapped[Purchase] = relationship(back_populates='entries', lazy="joined")
|
||||
product: Mapped[Product] = relationship(back_populates="purchases", lazy="joined")
|
||||
purchase: Mapped[Purchase] = relationship(back_populates="entries", lazy="joined")
|
||||
|
||||
def __init__(self, purchase, product, amount):
|
||||
self.product = product
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import (
|
||||
DateTime,
|
||||
@@ -18,8 +18,8 @@ from sqlalchemy.orm import (
|
||||
from .Base import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .User import User
|
||||
from .Purchase import Purchase
|
||||
from .User import User
|
||||
|
||||
|
||||
class Transaction(Base):
|
||||
@@ -36,7 +36,7 @@ class Transaction(Base):
|
||||
purchase_id: Mapped[int | None] = mapped_column(ForeignKey("purchases.id"))
|
||||
|
||||
user: Mapped[User] = relationship(lazy="joined")
|
||||
purchase: Mapped[Purchase] = relationship(back_populates='transactions', lazy="joined")
|
||||
purchase: Mapped[Purchase] = relationship(back_populates="transactions", lazy="joined")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import (
|
||||
Integer,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
)
|
||||
from sqlalchemy.orm import (
|
||||
Mapped,
|
||||
@@ -14,8 +15,8 @@ from sqlalchemy.orm import (
|
||||
from .Base import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .User import User
|
||||
from .Product import Product
|
||||
from .User import User
|
||||
|
||||
|
||||
class UserProducts(Base):
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import random
|
||||
import sys
|
||||
@@ -91,7 +90,9 @@ def main(sql_session: Session):
|
||||
exit_confirm_msg="Really quit Dibbler?",
|
||||
)
|
||||
if not config["general"]["quit_allowed"]:
|
||||
main_menu.exit_disallowed_msg = "You can check out any time you like, but you can never leave."
|
||||
main_menu.exit_disallowed_msg = (
|
||||
"You can check out any time you like, but you can never leave."
|
||||
)
|
||||
while True:
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import json
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -21,7 +20,7 @@ def main(sql_session: Session):
|
||||
product_items = []
|
||||
user_items = []
|
||||
|
||||
with open(JSON_FILE) as f:
|
||||
with Path.open(JSON_FILE) as f:
|
||||
json_obj = json.load(f)
|
||||
|
||||
for product in json_obj["products"]:
|
||||
|
||||
Reference in New Issue
Block a user