From 31e0ffd6dc95f554a66475b1980aad1bc237877a Mon Sep 17 00:00:00 2001 From: ske087 Date: Tue, 6 May 2025 16:20:04 +0300 Subject: [PATCH] added report lab options --- py_app/app/__pycache__/routes.cpython-311.pyc | Bin 25534 -> 27287 bytes py_app/app/routes.py | 39 +++++++++++++++++- py_app/app/static/script.js | 39 ++++++++++++++++++ py_app/app/templates/create_template.html | 9 +++- py_app/requirements.txt | 3 +- 5 files changed, 85 insertions(+), 5 deletions(-) diff --git a/py_app/app/__pycache__/routes.cpython-311.pyc b/py_app/app/__pycache__/routes.cpython-311.pyc index b55633986cd332d2e3c220bbf2e3f69d5de22201..a2bc35c7bf121358a2e043d5d4ebd649ef163207 100644 GIT binary patch delta 5004 zcmb_fYj7J^72aJvt(Rq6w&iDJ*@-Q`9p_;?Y2!5UBaQQDlg5wO5wdqJE0HDluAJ1a zgOoI-!GzlFr8I;>Ov|Knk`5hQpqVnIKnGeVAWao;#qfh+m}!`nrbEjkKN!xrYsvAW zLw~T^{dDhn-E;4rbI;z_e!)L|gSR|yHXAs&E*SGi+V6S7Vi$I6pQspV5jj!k&m7I_ z%i=j`>;1OT?7nQC6F5mDrb#(h1dh83k8<_piiUGspIyqG%cB`h*>y(IB$~a#HOq22 zG5s8O1yrsk6}i6rqz>)iotlDF?-A$~rg}eyUQx2A%elgX4W1f=0!?v}T4(>1G4oc9 zxh|Lrl^iZY9~-jQ&i_7bsDH; zNvgR_G@)H(dFb1!0?qm)kMe4#W<#oX7xct*LIqtowd36gw`*GLK4B&kSB1`BhO#aW~fYg;AKKR5|l%v;JKfr@tQ^; znC9O!*i?m^p-JorDCH8C+N6m7%Y0@Z;~7z)2|@uB+^8WJTe&c5RvQ#Vmy z9YQ@q1AvTEg<0Um{3JEVLf8TiO}9O4)f+D8W-QZ|+0!xo`nZ1m{3YA-ydD<{RBBiSdAm@x6#>_TbS2?l`jebqzLgf_zO$tEkKE0TIOR#pDG!lGg5$DOI}#f8 zlYOYR!qfqzA>2og+52GGuG{U}C0p+nS83VuZJsx*yR5Rdp!ha`gvu+0NF%-OtmR$w zJ!fg<{m43ma2VkMgd+&u2t5D^^-wSnAV=xu(#G;$AjlQ~wn8aTCU_sJAoR@7lzyx- z7Ga+S&^`3=^8CW(lYqbtdV}L3ava3IN#7`MgLxP#ZU|LOr5%+!0B)N{J-$G#3{mb2 zc;%(AbMeGZ4ON9kJBsEZG|`5tZJTkXBpm_6h1`X3H-Z%aqDK_TF=)BeOSVAsTUEKa zEOw1UMDm0rH@pEtf*|09@I{Jds3SNbyAm#;YjtPmWf%+(S>)zXDE`HFOC1YdA%iZ9*Sy z+;(s+huC6hMG3YKNpVL|RG1T3-I6XC6(PlmlfZ~m>!$Z$=znkejjD02q4PnA6d)8L zEWIGi=ff}1+fC1gnNJR6uaU(G{ix>z%$›mvSDzThSXigDdNOI}Orw)-y?Nzy) zu*#m3l3RKRCLFMO{BCiOgu#KE@W_9l8Mck{11&uU{w)2^o;UejG~Bj{-$-9>+rj73 zkK1;ZwxY8b#4iZstMHdlk>Dx$j+G)8>4#kvAbqBNqn1fOLa(>qRs#P?)P4$Jg@)%q zEvrDz_eJRTv{y(#*Iw$874Y^wA0UT{Q|Zh1GsJ4bqiVj#(k<^`IJwHdbzyp(Mt-795<+(a4+ zk`M@k&F_JXYF>Nauhe%GiU%5@R+*0!ty`Sb(-7 zTiG$k$NWK$sEqSNAotPg?tGB#=pHKn0gA0qFpUvkAmknmisOEXTnC9`G{!XE@Ag%$ zrIGIU3`%}?NE#jU!{#iLS3zlzhI??BOFh0#Ybq`7cWpD6+C}GC(sW!9CunhB`mfy^fgm8eP>HftEdz8SHO#_=n1<{YeVSS z;&mL8gI!ZvG3}aRxpAHYLp5z$(YTy`S{KSn>OmCXcQ3o9bW`dn&9HFIv_f7#rKcs8 zIrXA>N+Vh(K|xGk?iSAh$BLZOX;Z4*+(5}`gQ8RkN@-%ol;P{#H-uG6X<#lFl`c3z z++A5tUp1S;nPQe`dq!A(B7t*3_I{|5J~1?MQv`<-+7Zd;9SPmU_+}yFeed0CxBFkz zwkEW4$P@Anu}nHl9s+^M%;i~D3ojhb75XucSCV~`(oI~3n>LgTTe>hI9fuba@@556 z^}AU3wKygV4(@JuBm+lu$m2spk}MBHb($!dtgKUpu3J8wyrR#B7sxwc8GI0j-D956 zh|5CKfDk5eKqV_2*eXGABA5UYX(Sj7F$FS(L`=qnb{9J!B@80*oH`VOJ;<9-WAH1P zVPu&>evk6+B4COoOl&pXV?o%l~LF7DcCkFr`++U2DabrQu7%qw%iz2%h zOxBss>CV~ii$gJ!Gj4K5+7`?iGd5bmqywbESWPS(<8GJbIzD$ecZA> z(gE9&E$`yiCw4@-7Hs(!yJNPp$i7dsT(RSs?#um``d_SySMGS-9^Km?D;kIw4Mf%X ze^hJF?TuPDykv{2w}fNrEphc0Xn|68?pHdV?s~E-TCz3Tyf0?kAGhsi*3!~1m}f`7 zGxf?qw03V)-xbq$#r0j0oiMsa`&if6uG!4lfw}u*+2v7Jb4=Y5SGPpfEejdNbD6P> z(#X9FnR&N3L8HKV?SejS#x!l3z5inV1JU(OFKGebj_I4@`sS#{tr2I7EaCN8?^*pYCqQZ?bl z*7|*ewaMU@Ne0LytV>*YJ@BfO(9*lz_>t;%CxpQp zy0McIJN&Ri29c3=5+a*pAEm5bv+7H*qOu~%Qk4}kg0+cYsbSTEZTAE>ZWb>q%I$6a zcBRtZO+En;-1+6-sX6YJis$(SE-k`-3!Ei_Kf2!?E?eL#qs#9Ft~9#*p8vJ`PpX|J rPEbE)KWjfNsD0ODN_i`CA;~M=DOJSwT}cZ1MjK6S}c& delta 3421 zcmb_eYitx%6yCer=`P)FyU^EexAw6uY?neGEEEtZRG~$XP<)hjTUe&d&|RI~sduKf zzFJTeQ4=XQilPYyB7{I<%=#imjeo=!BtH1zh#G$>B>0H_BAR&4ozC`Y zAi4J2qJ?t7D@ANypr~Pvlq0$O?PqhR@+8lG+ervHV+Gox#a4_n?<4^a8T%z5lvqYq zO@e}tw@7O-+eNAbf5!I`_)4u-e(}^U+4m$M1T1gJXC}A$mHab=lv!L)DM%-lbhgtT z5N@)3&N9=-j@qk)@{F~7+^nzLsLr(fSwW#D)4Cg4^E0h6Xf4RJEOawxLxd(UWQFY$?=-;n_4NgLtc5EQjPk)mtR zmR_2_j*tKw^sXpv0fWhyBZ*qPPZg;|ZvkUHJMUdZTGEcW_t;4@OBFPEmm{|Tp%9^n zy;iVw^k#T99HOGoax_*TR3hXeR3QWrY7pilEI{CrowN<#+YuHbEJ9d}P>;|6py60y z82E6Zv<_VeOX0^JDSXK5oU?!Ez{sN`hmv17Yrb~Yq+La)hzn;5rgA-dySRxgXIF|B z`&%(IGi166n+O|OLrFJjVFydTnh2A8%OW`B2lIwRD#z79O|FmYNri64uxY8bpbcRw z``j0Wc?<@EOX0IaOOR1feticlDnRcL3YGg4VIWLZxL> z2VrDGk*I?@jRWmvwxo6gjAOX=lD&?HtjFLD0M|W9F_Eg*WL;0B`n8F=3lmz*hU?1Q z#YindXlBRiRxQJk(tHFg7rF{zHG&rasz;J&FT91bCUQY!{-Tl+UcBzzR2FqP1}i{m z5{SpsYZjFgP}jRywU+{)nvVm`w(sf^11vWL-8z*v$~$HQqH= z$8M8kcCCZsOE$9fXXv_r*+oZWwyu3ZqJD%@go$OrU3^!V#aA95<(mF&?;5V8crT2X zYK9XqB_?IQlMP{rCUiOMr2pDQW<$@|!G>28@0VlpFbp{56_uFOM;``3KfzD?mW>uJ zNq=^8R}L9v%BGJ=E4#K~DQRTEwzZ^)^|iHD^9_upd)iJJ{230a4r!BSiay77Y^eqI zuWd`RIeRY)wO=>O{aJ{hhq0@v5gnT&3xWiE&m$qz2R$;A3d!A^`XZ;MKiQ~|<&WX} zet_$_w{}#v4Ju0It*Ru`C(wQX;Yoyp2u~qAjqnVP@xO&N+_*4K9T#?ab1wPs%KLk@8$&8vlj>9>I@V|_>{l-Ocsws-~bRjz{fm0^5L|PQF%b6I*=jfYd|4secNYQlP-(S2;5f>b>37l+fDO2 zL{NlngkA8Jv9CJUz|A#xd%UU@J-l$uQ*&@YQANq@=MC_6v7_5df&1q6-Jvvcrv>B= z&_qg)B~@uqk?C8&=w)lWFe2KOSU6imz9RO?N=%oN0}33_8hr(pldtlTch0U7R z@uM*l^&$9@>~|jJ>3O{BqiF#-xDdM7r-115;G-9W%;x%BWpP=Ca zW|(wj7;a3lTU7>=DUDtP?=ZX8dmH3fzT;{muP7c)=vj=MB-X=^zl_u`!9B{h?OgA{ zwF@sYKcqrzMCu%M#bS8o#$txOZ-8P=8v=zZTIOGJ{6o$B9>T8}{{6wPdwzrSo08s# z4!kV*5zFh1R}aOC;ET)`jpCy4xu!UE=A2yQ-(#q6TB%%jtv0Kqg?ugWydM7nF4^>Q diff --git a/py_app/app/routes.py b/py_app/app/routes.py index ddf48c3..b81f66b 100644 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -4,6 +4,8 @@ from datetime import datetime, timedelta from flask import Blueprint, render_template, redirect, url_for, request, flash, session, current_app, jsonify from .models import User from . import db +from reportlab.lib.pagesizes import letter +from reportlab.pdfgen import canvas bp = Blueprint('main', __name__) @@ -61,7 +63,7 @@ def settings(): # Load external database settings from the instance folder external_settings = {} settings_file = os.path.join(current_app.instance_path, 'external_server.conf') - if os.path.exists(settings_file): + if (os.path.exists(settings_file)): with open(settings_file, 'r') as f: for line in f: key, value = line.strip().split('=', 1) @@ -385,4 +387,37 @@ def save_template(): data = request.get_json() # Replace with logic to save the template to the database print(f"Saving template: {data}") - return jsonify({'message': 'Template saved successfully!'}) \ No newline at end of file + return jsonify({'message': 'Template saved successfully!'}) + +@bp.route('/generate_pdf', methods=['POST']) +def generate_pdf(): + data = request.get_json() + width = data.get('width', 100) # Default width in mm + height = data.get('height', 50) # Default height in mm + columns = data.get('columns', []) + + # Convert dimensions from mm to points (1 mm = 2.83465 points) + width_points = width * 2.83465 + height_points = height * 2.83465 + + # Ensure the /static/label_templates folder exists + label_templates_folder = os.path.join(current_app.root_path, 'static', 'label_templates') + os.makedirs(label_templates_folder, exist_ok=True) + + # Define the path for the PDF file + pdf_file_path = os.path.join(label_templates_folder, 'label_template.pdf') + + # Create a PDF file + c = canvas.Canvas(pdf_file_path, pagesize=(width_points, height_points)) + + # Add content to the PDF + c.drawString(10, height_points - 20, "Label Template") + y_position = height_points - 40 + for column in columns: + c.drawString(10, y_position, f"Column: {column}") + y_position -= 20 + + # Save the PDF + c.save() + + return jsonify({'message': 'PDF generated successfully!', 'pdf_path': f'/static/label_templates/label_template.pdf'}) \ No newline at end of file diff --git a/py_app/app/static/script.js b/py_app/app/static/script.js index 449d893..df51ff9 100644 --- a/py_app/app/static/script.js +++ b/py_app/app/static/script.js @@ -303,4 +303,43 @@ document.addEventListener('DOMContentLoaded', () => { }) .catch(error => console.error('Error saving template:', error)); }); + + document.getElementById('generate-pdf-btn').addEventListener('click', () => { + const width = document.getElementById('label-width').value; + const height = document.getElementById('label-height').value; + const selectedColumns = Array.from(document.querySelectorAll('#columns-container input[type="checkbox"]:checked')) + .map(checkbox => checkbox.value); + + if (!width || !height || selectedColumns.length === 0) { + alert('Please set dimensions and select at least one column.'); + return; + } + + const data = { + width: parseFloat(width), + height: parseFloat(height), + columns: selectedColumns + }; + + fetch('/generate_pdf', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }) + .then(response => response.json()) + .then(result => { + alert(result.message); + console.log('PDF Path:', result.pdf_path); + + // Provide a link to download the PDF + const downloadLink = document.createElement('a'); + downloadLink.href = result.pdf_path; + downloadLink.textContent = 'Download Generated PDF'; + downloadLink.target = '_blank'; + document.getElementById('label-preview').appendChild(downloadLink); + }) + .catch(error => console.error('Error generating PDF:', error)); + }); }); \ No newline at end of file diff --git a/py_app/app/templates/create_template.html b/py_app/app/templates/create_template.html index 020c300..c450b94 100644 --- a/py_app/app/templates/create_template.html +++ b/py_app/app/templates/create_template.html @@ -22,7 +22,6 @@ - @@ -40,6 +39,13 @@ + +
+ + +
+ +
@@ -51,7 +57,6 @@
- diff --git a/py_app/requirements.txt b/py_app/requirements.txt index ca93b96..9a8a97c 100644 --- a/py_app/requirements.txt +++ b/py_app/requirements.txt @@ -4,4 +4,5 @@ Werkzeug gunicorn flask-sqlalchemy pyodbc -mariadb \ No newline at end of file +mariadb +reportlab \ No newline at end of file