Merge branch 'main' of https://gitea.sekidesu.xyz/SekiDesu01/SekiPOS
This commit is contained in:
28
app.py
28
app.py
@@ -10,6 +10,9 @@ import mimetypes
|
|||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import zipfile
|
||||||
|
import io
|
||||||
|
|
||||||
# from dotenv import load_dotenv
|
# from dotenv import load_dotenv
|
||||||
|
|
||||||
# load_dotenv()
|
# load_dotenv()
|
||||||
@@ -532,6 +535,31 @@ def export_db():
|
|||||||
return send_file(DB_FILE, as_attachment=True, download_name=f"SekiPOS_Backup_{datetime.now().strftime('%Y%m%d')}.db", mimetype='application/x-sqlite3')
|
return send_file(DB_FILE, as_attachment=True, download_name=f"SekiPOS_Backup_{datetime.now().strftime('%Y%m%d')}.db", mimetype='application/x-sqlite3')
|
||||||
return "Error: Database file not found", 404
|
return "Error: Database file not found", 404
|
||||||
|
|
||||||
|
@app.route('/export/images')
|
||||||
|
@login_required
|
||||||
|
def export_images():
|
||||||
|
if not os.path.exists(CACHE_DIR) or not os.listdir(CACHE_DIR):
|
||||||
|
return "No images found to export", 404
|
||||||
|
|
||||||
|
# Create an in-memory byte stream to hold the zip data
|
||||||
|
memory_file = io.BytesIO()
|
||||||
|
|
||||||
|
with zipfile.ZipFile(memory_file, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||||
|
for root, dirs, files in os.walk(CACHE_DIR):
|
||||||
|
for file in files:
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
# Store files using their names only to avoid nesting inside the zip
|
||||||
|
zf.write(file_path, arcname=file)
|
||||||
|
|
||||||
|
memory_file.seek(0)
|
||||||
|
|
||||||
|
return send_file(
|
||||||
|
memory_file,
|
||||||
|
mimetype='application/zip',
|
||||||
|
as_attachment=True,
|
||||||
|
download_name=f"SekiPOS_Images_{datetime.now().strftime('%Y%m%d')}.zip"
|
||||||
|
)
|
||||||
|
|
||||||
# @app.route('/process_payment', methods=['POST'])
|
# @app.route('/process_payment', methods=['POST'])
|
||||||
# @login_required
|
# @login_required
|
||||||
# def process_payment():
|
# def process_payment():
|
||||||
|
|||||||
10
migrate.py
10
migrate.py
@@ -5,6 +5,16 @@ DB_FILE = 'db/pos_database.db'
|
|||||||
def upgrade_db():
|
def upgrade_db():
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(DB_FILE) as conn:
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
# Add stock column
|
||||||
|
# conn.execute("ALTER TABLE products ADD COLUMN stock REAL DEFAULT 0")
|
||||||
|
# print("Successfully added 'stock' column.")
|
||||||
|
|
||||||
|
# # App.py also expects unit_type, adding it to prevent future headaches
|
||||||
|
# conn.execute("ALTER TABLE products ADD COLUMN unit_type TEXT DEFAULT 'unit'")
|
||||||
|
# print("Successfully added 'unit_type' column.")
|
||||||
|
>>>>>>> 1a048a0e074ee26bd45dda9731c78c2ecef42fba
|
||||||
|
|
||||||
conn.execute("ALTER TABLE dicom ADD COLUMN image_url TEXT;")
|
conn.execute("ALTER TABLE dicom ADD COLUMN image_url TEXT;")
|
||||||
print("Successfully added 'image_url' column.")
|
print("Successfully added 'image_url' column.")
|
||||||
|
|||||||
@@ -49,14 +49,39 @@
|
|||||||
<div id="receipt-print-zone{{ id_suffix }}" class="d-none d-print-block">
|
<div id="receipt-print-zone{{ id_suffix }}" class="d-none d-print-block">
|
||||||
<style>
|
<style>
|
||||||
@media print {
|
@media print {
|
||||||
body * { visibility: hidden; }
|
/* Tell the browser this is a continuous 80mm thermal roll */
|
||||||
#receipt-print-zone{{ id_suffix }}, #receipt-print-zone{{ id_suffix }} * { visibility: visible; }
|
@page {
|
||||||
|
margin: 0;
|
||||||
|
size: 80mm auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nuke the rest of the layout from the document flow so it takes up 0 height */
|
||||||
|
nav, .discord-card, .modal, .row {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body * {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resurrect the receipt and put it in the top left corner */
|
||||||
|
#receipt-print-zone{{ id_suffix }}, #receipt-print-zone{{ id_suffix }} * {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
#receipt-print-zone{{ id_suffix }} {
|
#receipt-print-zone{{ id_suffix }} {
|
||||||
position: absolute; left: 0; top: 0; width: 80mm;
|
position: absolute;
|
||||||
padding: 5mm; margin: 0; display: block !important;
|
left: 0;
|
||||||
font-family: 'Courier New', Courier, monospace; font-size: 10px; color: #000;
|
top: 0;
|
||||||
|
width: 80mm;
|
||||||
|
padding: 2mm 5mm;
|
||||||
|
margin: 0;
|
||||||
|
display: block !important;
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.receipt-table { width: 100%; border-collapse: collapse; font-family: monospace; font-size: 12px; }
|
.receipt-table { width: 100%; border-collapse: collapse; font-family: monospace; font-size: 12px; }
|
||||||
.receipt-header { text-align: center; margin-bottom: 10px; border-bottom: 1px dashed #000; padding-bottom: 5px; }
|
.receipt-header { text-align: center; margin-bottom: 10px; border-bottom: 1px dashed #000; padding-bottom: 5px; }
|
||||||
.receipt-total-row { border-top: 1px dashed #000; margin-top: 5px; padding-top: 5px; font-weight: bold; }
|
.receipt-total-row { border-top: 1px dashed #000; margin-top: 5px; padding-top: 5px; font-weight: bold; }
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
<i class="bi bi-database-down me-2"></i>Descargar DB
|
<i class="bi bi-database-down me-2"></i>Descargar DB
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="/export/images">
|
||||||
|
<i class="bi bi-images me-2"></i>Descargar Imágenes
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li><hr class="dropdown-divider"></li>
|
<li><hr class="dropdown-divider"></li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item text-danger" href="/logout">
|
<a class="dropdown-item text-danger" href="/logout">
|
||||||
|
|||||||
Reference in New Issue
Block a user