feat(pos): add 3 improvements — Spanish translations, PDF quotes, push notifications
1. Spanish translations for TecDoc catalog (translations.py) applied to catalog_service.py and dashboard server.py endpoints 2. Printable quotation HTML endpoint (/pos/api/quotations/<id>/pdf) with @media print CSS for clean browser-to-PDF output 3. Web Push notifications to owner/admin on sale cancellation, stock zero, and cash register differences > $500. Includes service worker, VAPID key management, and subscription endpoints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,10 @@ import urllib.request
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'pos'))
|
||||
from config import DB_URL
|
||||
from auth import hash_password, check_password, create_access_token, create_refresh_token, decode_token, require_auth
|
||||
from services.translations import translate_part_name, translate_category
|
||||
|
||||
app = Flask(__name__, static_folder='.')
|
||||
|
||||
@@ -402,7 +404,7 @@ def api_catalog_categories():
|
||||
ORDER BY name
|
||||
"""), {'mye_id': mye_id}).mappings().all()
|
||||
return jsonify([{'id_part_category': r['id_part_category'],
|
||||
'name': r['name'], 'part_count': r['part_count']} for r in rows])
|
||||
'name': translate_category(r['name']), 'part_count': r['part_count']} for r in rows])
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
@@ -428,7 +430,7 @@ def api_catalog_groups():
|
||||
ORDER BY name
|
||||
"""), {'mye_id': mye_id, 'category_id': category_id}).mappings().all()
|
||||
return jsonify([{'id_part_group': r['id_part_group'],
|
||||
'name': r['name'], 'part_count': r['part_count']} for r in rows])
|
||||
'name': translate_category(r['name']), 'part_count': r['part_count']} for r in rows])
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
@@ -464,7 +466,7 @@ def api_catalog_parts():
|
||||
items = [{
|
||||
'id_part': r['id_part'],
|
||||
'oem_part_number': r['oem_part_number'],
|
||||
'name': r['name_es'] or r['name_part'],
|
||||
'name': translate_part_name(r['name_es'] or r['name_part']),
|
||||
'description': r['description_es'] or r['description'],
|
||||
'image_url': r['image_url'],
|
||||
} for r in rows]
|
||||
@@ -497,11 +499,11 @@ def api_catalog_part_detail(part_id):
|
||||
part = {
|
||||
'id_part': row['id_part'],
|
||||
'oem_part_number': row['oem_part_number'],
|
||||
'name': row['name_es'] or row['name_part'],
|
||||
'name': translate_part_name(row['name_es'] or row['name_part']),
|
||||
'description': row['description_es'] or row['description'],
|
||||
'image_url': row['image_url'],
|
||||
'group_name': row['group_name'],
|
||||
'category_name': row['category_name'],
|
||||
'group_name': translate_category(row['group_name']) if row['group_name'] else row['group_name'],
|
||||
'category_name': translate_category(row['category_name']) if row['category_name'] else row['category_name'],
|
||||
}
|
||||
|
||||
# Cross-references
|
||||
@@ -615,7 +617,7 @@ def api_catalog_search():
|
||||
results.append({
|
||||
'id_part': r['id_part'],
|
||||
'oem_part_number': r['oem_part_number'],
|
||||
'name': r['name_es'] or r['name_part'],
|
||||
'name': translate_part_name(r['name_es'] or r['name_part']),
|
||||
'image_url': r['image_url'],
|
||||
'vehicle_info': vmap.get(r['id_part'], ''),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user