Test_DB / invoice_app.py
Antoni09's picture
Upload 10 files
9c4e7c0 verified
import getpass
import hashlib
import json
import os
from datetime import datetime
DATA_FILE = "invoice_data.json"
INVOICE_FOLDER = "invoices"
def hash_password(password: str) -> str:
return hashlib.sha256(password.encode("utf-8")).hexdigest()
def prompt_non_empty(prompt: str) -> str:
while True:
value = input(prompt).strip()
if value:
return value
print("Pole nie moze byc puste.")
def prompt_positive_float(prompt: str) -> float:
while True:
raw_value = input(prompt).replace(",", ".").strip()
try:
value = float(raw_value)
except ValueError:
print("Wprowadz liczbe.")
continue
if value <= 0:
print("Wartosc musi byc wieksza od zera.")
continue
return value
def load_data():
if not os.path.exists(DATA_FILE):
return None
with open(DATA_FILE, "r", encoding="utf-8") as handle:
return json.load(handle)
def save_data(data) -> None:
with open(DATA_FILE, "w", encoding="utf-8") as handle:
json.dump(data, handle, indent=2, ensure_ascii=False)
def run_setup():
print("=== Konfiguracja konta przedsiebiorcy ===")
business = {
"company_name": prompt_non_empty("Nazwa firmy: "),
"owner_name": prompt_non_empty("Imie i nazwisko wlasciciela: "),
"address": prompt_non_empty("Adres: "),
"tax_id": prompt_non_empty("NIP: "),
"bank_account": prompt_non_empty("Numer konta bankowego: "),
}
print("\nUstaw haslo do logowania.")
while True:
password = getpass.getpass("Haslo: ")
confirm = getpass.getpass("Powtorz haslo: ")
if not password:
print("Haslo nie moze byc puste.")
continue
if password != confirm:
print("Hasla nie sa identyczne. Sprobuj ponownie.")
continue
break
data = {
"business": business,
"password_hash": hash_password(password),
"invoices": [],
}
save_data(data)
print("\nDane zapisane. Uruchom aplikacje ponownie, aby zalogowac sie i wystawiac faktury.")
def authenticate(data) -> bool:
for attempt in range(3):
password = getpass.getpass("Haslo: ")
if hash_password(password) == data["password_hash"]:
return True
print("Nieprawidlowe haslo.")
return False
def prompt_client_details():
answer = input("Dodac dane klienta? (T/N): ").strip().lower()
if answer not in ("t", "tak"):
return {}
print("\n=== Dane klienta ===")
client = {
"name": prompt_non_empty("Nazwa / Imie i nazwisko: "),
"address": prompt_non_empty("Adres: "),
"tax_id": input("NIP (opcjonalnie): ").strip(),
}
return client
def format_invoice_text(invoice_id: str, business: dict, invoice: dict) -> str:
lines = [
f"Faktura: {invoice_id}",
f"Data wystawienia: {invoice['issued_at']}",
"",
"=== Sprzedawca ===",
f"Nazwa: {business['company_name']}",
f"Wlasciciel: {business['owner_name']}",
f"Adres: {business['address']}",
f"NIP: {business['tax_id']}",
f"Konto bankowe: {business['bank_account']}",
"",
"=== Nabywca ===",
]
client = invoice.get("client", {})
if client:
lines.extend(
[
f"Nazwa: {client.get('name', '')}",
f"Adres: {client.get('address', '')}",
f"NIP: {client.get('tax_id', '') or '---'}",
]
)
else:
lines.append("Brak danych klienta (pole opcjonalne).")
lines.extend(
[
"",
"=== Pozycja ===",
f"Opis: {invoice['item_description']}",
f"Ilosc: {invoice['quantity']}",
f"Cena jednostkowa: {invoice['unit_price']:.2f} PLN",
f"Wartosc netto: {invoice['net_total']:.2f} PLN",
]
)
return "\n".join(lines)
def create_invoice(data):
print("\n=== Wystaw fakture ===")
description = prompt_non_empty("Opis uslugi / towaru: ")
quantity = prompt_positive_float("Ilosc: ")
unit_price = prompt_positive_float("Cena jednostkowa (PLN): ")
client = prompt_client_details()
issued_at = datetime.now().strftime("%Y-%m-%d %H:%M")
invoice_id = datetime.now().strftime("FV-%Y%m%d-%H%M%S")
net_total = quantity * unit_price
invoice = {
"invoice_id": invoice_id,
"issued_at": issued_at,
"item_description": description,
"quantity": quantity,
"unit_price": unit_price,
"net_total": net_total,
"client": client,
}
os.makedirs(INVOICE_FOLDER, exist_ok=True)
invoice_path = os.path.join(INVOICE_FOLDER, f"{invoice_id}.txt")
with open(invoice_path, "w", encoding="utf-8") as handle:
handle.write(format_invoice_text(invoice_id, data["business"], invoice))
data["invoices"].append(invoice)
save_data(data)
print(f"\nFaktura zapisana do {invoice_path}")
print(f"Suma do zaplaty: {net_total:.2f} PLN")
def main():
data = load_data()
if data is None:
run_setup()
return
print("=== Logowanie ===")
if not authenticate(data):
print("Zbyt wiele nieudanych prob logowania. Zakonczono.")
return
create_invoice(data)
if __name__ == "__main__":
main()