migrated more receipts module api
This commit is contained in:
parent
ee2bdda226
commit
cb240f7e97
@ -104,18 +104,17 @@ def getReceipt():
|
|||||||
return jsonify({'receipt': record, 'error': False, "message": "Get Receipts Successful!"})
|
return jsonify({'receipt': record, 'error': False, "message": "Get Receipts Successful!"})
|
||||||
return jsonify({'receipt': record, 'error': True, "message": "Something went wrong while getting receipts!"})
|
return jsonify({'receipt': record, 'error': True, "message": "Something went wrong while getting receipts!"})
|
||||||
|
|
||||||
|
# added to database
|
||||||
@receipt_api.route('/api/addReceipt', methods=["POST", "GET"])
|
@receipt_api.route('/api/addReceipt', methods=["POST", "GET"])
|
||||||
def addReceipt():
|
def addReceipt():
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
user_id = session['user_id']
|
user_id = session['user_id']
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
receipt = database_payloads.ReceiptPayload(
|
||||||
with psycopg2.connect(**database_config) as conn:
|
receipt_id=f"PR-{receipts_database.requestNextReceiptID(site_name)}",
|
||||||
receipt = MyDataclasses.ReceiptPayload(
|
submitted_by=user_id
|
||||||
receipt_id=f"PR-{database.request_receipt_id(conn, site_name)}",
|
)
|
||||||
submitted_by=user_id
|
receipts_database.insertReceiptsTuple(site_name, receipt.payload())
|
||||||
)
|
|
||||||
database.insertReceiptsTuple(conn, site_name, receipt.payload())
|
|
||||||
return jsonify({'error': False, "message": "Receipt Added Successful!"})
|
return jsonify({'error': False, "message": "Receipt Added Successful!"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while adding receipt!"})
|
return jsonify({'error': True, "message": "Something went wrong while adding receipt!"})
|
||||||
|
|
||||||
@ -145,41 +144,37 @@ def addSKULine():
|
|||||||
return jsonify({'error': False, "message": "Line added Succesfully"})
|
return jsonify({'error': False, "message": "Line added Succesfully"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while add SKU line!"})
|
return jsonify({'error': True, "message": "Something went wrong while add SKU line!"})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@receipt_api.route('/api/deleteLine', methods=["POST"])
|
@receipt_api.route('/api/deleteLine', methods=["POST"])
|
||||||
def deleteLine():
|
def deleteLine():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
line_id = int(request.get_json()['line_id'])
|
line_id = int(request.get_json()['line_id'])
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
receipts_database.deleteReceiptItemsTuple(site_name, (line_id, ))
|
||||||
with psycopg2.connect(**database_config) as conn:
|
|
||||||
database.deleteReceiptItemsTuple(conn, site_name, (line_id, ))
|
|
||||||
|
|
||||||
return jsonify({'error': False, "message": "Line Deleted Succesfully"})
|
return jsonify({'error': False, "message": "Line Deleted Succesfully"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while deleting line!"})
|
return jsonify({'error': True, "message": "Something went wrong while deleting line!"})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@receipt_api.route('/api/denyLine', methods=["POST"])
|
@receipt_api.route('/api/denyLine', methods=["POST"])
|
||||||
def denyLine():
|
def denyLine():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
line_id = int(request.get_json()['line_id'])
|
line_id = int(request.get_json()['line_id'])
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
receipts_database.updateReceiptItemsTuple(site_name, {'id': line_id, 'update': {'status': 'Denied'}})
|
||||||
with psycopg2.connect(**database_config) as conn:
|
|
||||||
database.__updateTuple(conn, site_name, f"{site_name}_receipt_items", {'id': line_id, 'update': {'status': 'Denied'}})
|
|
||||||
return jsonify({'error': False, "message": "Line Denied Succesfully"})
|
return jsonify({'error': False, "message": "Line Denied Succesfully"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while denying line!"})
|
return jsonify({'error': True, "message": "Something went wrong while denying line!"})
|
||||||
|
|
||||||
|
# Added to database
|
||||||
@receipt_api.route('/api/saveLine', methods=["POST"])
|
@receipt_api.route('/api/saveLine', methods=["POST"])
|
||||||
def saveLine():
|
def saveLine():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
line_id = int(request.get_json()['line_id'])
|
line_id = int(request.get_json()['line_id'])
|
||||||
payload = request.get_json()['payload']
|
payload = request.get_json()['payload']
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
receipt_item = receipts_database.selectReceiptItemsTuple(site_name, (line_id, ))
|
||||||
with psycopg2.connect(**database_config) as conn:
|
if 'api_data' in receipt_item['data'].keys():
|
||||||
receipt_item = database.__selectTuple(conn, site_name, f"{site_name}_receipt_items", (line_id, ), convert=True)
|
payload['data']['api_data'] = receipt_item['data']['api_data']
|
||||||
if 'api_data' in receipt_item['data'].keys():
|
receipts_database.updateReceiptItemsTuple(site_name, {'id': line_id, 'update': payload})
|
||||||
payload['data']['api_data'] = receipt_item['data']['api_data']
|
|
||||||
database.__updateTuple(conn, site_name, f"{site_name}_receipt_items", {'id': line_id, 'update': payload})
|
|
||||||
return jsonify({'error': False, "message": "Line Saved Succesfully"})
|
return jsonify({'error': False, "message": "Line Saved Succesfully"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while saving line!"})
|
return jsonify({'error': True, "message": "Something went wrong while saving line!"})
|
||||||
|
|
||||||
@ -377,9 +372,12 @@ def uploadFile(receipt_id):
|
|||||||
|
|
||||||
return jsonify({})
|
return jsonify({})
|
||||||
|
|
||||||
|
# Does not need to be added to Database
|
||||||
@receipt_api.route('/api/getFile/<file_name>')
|
@receipt_api.route('/api/getFile/<file_name>')
|
||||||
def getFile(file_name):
|
def getFile(file_name):
|
||||||
return send_from_directory('static/files/receipts', file_name)
|
path_ = current_app.config['FILES_FOLDER'] + "/receipts"
|
||||||
|
print(path_)
|
||||||
|
return send_from_directory(path_, file_name)
|
||||||
|
|
||||||
@receipt_api.route('/api/checkAPI', methods=["POST"])
|
@receipt_api.route('/api/checkAPI', methods=["POST"])
|
||||||
def checkAPI():
|
def checkAPI():
|
||||||
@ -390,7 +388,7 @@ def checkAPI():
|
|||||||
database_config = config()
|
database_config = config()
|
||||||
with psycopg2.connect(**database_config) as conn:
|
with psycopg2.connect(**database_config) as conn:
|
||||||
print(barcode, line_id)
|
print(barcode, line_id)
|
||||||
api_response, api_data = get_open_facts(barcode)
|
api_response, api_data = receipts_processes.get_open_facts(barcode)
|
||||||
if api_response:
|
if api_response:
|
||||||
receipt_item = database.__selectTuple(conn, site_name, f"{site_name}_receipt_items", (line_id, ), convert=True)
|
receipt_item = database.__selectTuple(conn, site_name, f"{site_name}_receipt_items", (line_id, ), convert=True)
|
||||||
item_data = receipt_item['data']
|
item_data = receipt_item['data']
|
||||||
@ -405,16 +403,4 @@ def checkAPI():
|
|||||||
else:
|
else:
|
||||||
return jsonify({'error': True, "message": "Item not in WorldFoodFacts!"})
|
return jsonify({'error': True, "message": "Item not in WorldFoodFacts!"})
|
||||||
return jsonify({'error': False, "message": "Line Saved Succesfully"})
|
return jsonify({'error': False, "message": "Line Saved Succesfully"})
|
||||||
return jsonify({'error': True, "message": "Something went wrong while saving line!"})
|
return jsonify({'error': True, "message": "Something went wrong while saving line!"})
|
||||||
|
|
||||||
open_food_api = openfoodfacts.API(user_agent="MyAwesomeApp/1.0")
|
|
||||||
|
|
||||||
open_food_enabled = True
|
|
||||||
|
|
||||||
def get_open_facts(barcode):
|
|
||||||
if open_food_enabled:
|
|
||||||
barcode: str = barcode.replace('%', "")
|
|
||||||
data = open_food_api.product.get(barcode)
|
|
||||||
if data != None:
|
|
||||||
return True, data
|
|
||||||
return False, {}
|
|
||||||
@ -1,9 +1,48 @@
|
|||||||
import psycopg2
|
import psycopg2
|
||||||
|
|
||||||
|
|
||||||
import config
|
import config
|
||||||
from application import postsqldb
|
from application import postsqldb
|
||||||
|
|
||||||
|
def requestNextReceiptID(site_name, conn=None):
|
||||||
|
"""gets the next id for receipts_id, currently returns a 8 digit number
|
||||||
|
|
||||||
|
Args:
|
||||||
|
site (str): site to get the next id for
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
json: receipt_id, message, error keys
|
||||||
|
"""
|
||||||
|
next_receipt_id = None
|
||||||
|
self_conn = False
|
||||||
|
sql = f"SELECT receipt_id FROM {site_name}_receipts ORDER BY id DESC LIMIT 1;"
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql)
|
||||||
|
next_receipt_id = cur.fetchone()
|
||||||
|
if next_receipt_id == None:
|
||||||
|
next_receipt_id = "00000001"
|
||||||
|
else:
|
||||||
|
next_receipt_id = next_receipt_id[0]
|
||||||
|
next_receipt_id = int(next_receipt_id.split("-")[1]) + 1
|
||||||
|
y = str(next_receipt_id)
|
||||||
|
len_str = len(y)
|
||||||
|
x = "".join(["0" for _ in range(8 - len_str)])
|
||||||
|
next_receipt_id = x + y
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return next_receipt_id
|
||||||
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload=(), sql=sql)
|
||||||
|
|
||||||
def getItemsWithQOH(site, payload, convert=True, conn=None):
|
def getItemsWithQOH(site, payload, convert=True, conn=None):
|
||||||
recordset = []
|
recordset = []
|
||||||
count = 0
|
count = 0
|
||||||
@ -69,7 +108,59 @@ def getItemAllByID(site, payload, convert=True, conn=None):
|
|||||||
except (Exception, psycopg2.DatabaseError) as error:
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, getItemAllByID_sql)
|
raise postsqldb.DatabaseError(error, payload, getItemAllByID_sql)
|
||||||
|
|
||||||
|
def selectReceiptItemsTuple(site, payload, convert=True, conn=None):
|
||||||
|
selected = ()
|
||||||
|
self_conn = False
|
||||||
|
sql = f"SELECT * FROM {site}_receipt_items WHERE id=%s;"
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
selected = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
if rows and not convert:
|
||||||
|
selected = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return selected
|
||||||
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def deleteReceiptItemsTuple(site, payload, convert=True, conn=None):
|
||||||
|
deleted = ()
|
||||||
|
self_conn = False
|
||||||
|
sql = f"WITH deleted_rows AS (DELETE FROM {site}_receipt_items WHERE id IN ({','.join(['%s'] * len(payload))}) RETURNING *) SELECT * FROM deleted_rows;"
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
if rows and convert:
|
||||||
|
deleted = [postsqldb.tupleDictionaryFactory(cur.description, r) for r in rows]
|
||||||
|
elif rows and not convert:
|
||||||
|
deleted = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return deleted
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
def insertReceiptItemsTuple(site, payload, convert=True, conn=None):
|
def insertReceiptItemsTuple(site, payload, convert=True, conn=None):
|
||||||
receipt_item = ()
|
receipt_item = ()
|
||||||
@ -96,5 +187,79 @@ def insertReceiptItemsTuple(site, payload, convert=True, conn=None):
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
return receipt_item
|
return receipt_item
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def insertReceiptsTuple(site, payload, convert=True, conn=None):
|
||||||
|
receipt = ()
|
||||||
|
self_conn = False
|
||||||
|
with open(f"application/receipts/sql/insertReceiptsTuple.sql", "r+") as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
receipt = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
elif rows and not convert:
|
||||||
|
receipt = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return receipt
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def updateReceiptItemsTuple(site, payload, convert=True, conn=None):
|
||||||
|
"""_summary_
|
||||||
|
|
||||||
|
Args:
|
||||||
|
conn (_T_connector@connect): Postgresql Connector
|
||||||
|
site (str):
|
||||||
|
payload (dict): {'id': row_id, 'update': {... column_to_update: value_to_update_to...}}
|
||||||
|
convert (bool, optional): determines if to return tuple as dictionary. Defaults to True.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
DatabaseError:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple or dict: updated tuple
|
||||||
|
"""
|
||||||
|
updated = ()
|
||||||
|
self_conn = False
|
||||||
|
|
||||||
|
set_clause, values = postsqldb.updateStringFactory(payload['update'])
|
||||||
|
values.append(payload['id'])
|
||||||
|
sql = f"UPDATE {site}_receipt_items SET {set_clause} WHERE id=%s RETURNING *;"
|
||||||
|
try:
|
||||||
|
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, values)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
updated = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
elif rows and not convert:
|
||||||
|
updated = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return updated
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, sql)
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import pymupdf
|
import pymupdf
|
||||||
import os
|
import os
|
||||||
import PIL
|
import PIL
|
||||||
|
import openfoodfacts
|
||||||
|
|
||||||
def create_pdf_preview(pdf_path, output_path, size=(600, 400)):
|
def create_pdf_preview(pdf_path, output_path, size=(600, 400)):
|
||||||
pdf = pymupdf.open(pdf_path)
|
pdf = pymupdf.open(pdf_path)
|
||||||
@ -11,4 +12,17 @@ def create_pdf_preview(pdf_path, output_path, size=(600, 400)):
|
|||||||
output_path = output_path + file_name + '.jpg'
|
output_path = output_path + file_name + '.jpg'
|
||||||
img.thumbnail(size)
|
img.thumbnail(size)
|
||||||
img.save(output_path)
|
img.save(output_path)
|
||||||
return file_name + '.jpg'
|
return file_name + '.jpg'
|
||||||
|
|
||||||
|
|
||||||
|
# OPEN FOOD FACTS API INTEGRATION
|
||||||
|
open_food_api = openfoodfacts.API(user_agent="MyAwesomeApp/1.0")
|
||||||
|
open_food_enabled = True
|
||||||
|
|
||||||
|
def get_open_facts(barcode):
|
||||||
|
if open_food_enabled:
|
||||||
|
barcode: str = barcode.replace('%', "")
|
||||||
|
data = open_food_api.product.get(barcode)
|
||||||
|
if data != None:
|
||||||
|
return True, data
|
||||||
|
return False, {}
|
||||||
4
application/receipts/sql/insertReceiptsTuple.sql
Normal file
4
application/receipts/sql/insertReceiptsTuple.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
INSERT INTO %%site_name%%_receipts
|
||||||
|
(receipt_id, receipt_status, date_submitted, submitted_by, vendor_id, files)
|
||||||
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
|
RETURNING *;
|
||||||
@ -250,7 +250,7 @@ async function viewFile(source) {
|
|||||||
document.getElementById('filenameiframemodal').innerHTML = source
|
document.getElementById('filenameiframemodal').innerHTML = source
|
||||||
|
|
||||||
let iframe = document.createElement('iframe')
|
let iframe = document.createElement('iframe')
|
||||||
iframe.src = `/receipt/getFile/${source}`
|
iframe.src = `/receipts/api/getFile/${source}`
|
||||||
iframe.width = "100%"
|
iframe.width = "100%"
|
||||||
iframe.style.height = "100%"
|
iframe.style.height = "100%"
|
||||||
|
|
||||||
|
|||||||
@ -91,12 +91,12 @@
|
|||||||
<div class="uk-container">
|
<div class="uk-container">
|
||||||
<div class="uk-section">
|
<div class="uk-section">
|
||||||
<div uk-grid>
|
<div uk-grid>
|
||||||
<div class="uk-width-1-2@m">
|
<!-- div class="uk-width-1-2@m">
|
||||||
<ul class="uk-iconnav uk-flex-center uk-flex-left@m">
|
<ul class="uk-iconnav uk-flex-center uk-flex-left@m">
|
||||||
<li><a href="#" uk-icon="icon: plus">Open Receipt</a></li>
|
<li><a href="#" uk-icon="icon: plus">Open Receipt</a></li>
|
||||||
<li><a href="#" uk-icon="icon: cloud-download">download</a></li>
|
<li><a href="#" uk-icon="icon: cloud-download">download</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div -->
|
||||||
<div class="uk-width-1-2@m">
|
<div class="uk-width-1-2@m">
|
||||||
<nav aria-label="Pagination">
|
<nav aria-label="Pagination">
|
||||||
<ul id="paginationElement" class="uk-pagination uk-flex-center uk-flex-right@m" uk-margin>
|
<ul id="paginationElement" class="uk-pagination uk-flex-center uk-flex-right@m" uk-margin>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
Loading…
x
Reference in New Issue
Block a user