feat: intake page rework, new Pallet fields, address fix, button rename, COR generator, theme CSS

This commit is contained in:
Westech Admin
2026-05-22 05:15:09 +00:00
parent 3c11969c89
commit be06bca0cf
16 changed files with 419 additions and 800 deletions
+98
View File
@@ -0,0 +1,98 @@
import frappe
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib.colors import HexColor
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER
from reportlab.lib import colors
import sqlite3
import io
DB_PATH = '/opt/eim/eim.db'
DARK_BLUE = HexColor('#2F5496')
LIGHT_BLUE = HexColor('#D6E4F0')
GRAY = HexColor('#666666')
def get_device_counts(pallet_number):
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
cur = conn.cursor()
cur.execute('SELECT device_type, COUNT(*) as count FROM devices WHERE pallet_number = ? GROUP BY device_type', (pallet_number,))
counts = {row['device_type']: row['count'] for row in cur.fetchall()}
conn.close()
return counts
@frappe.whitelist()
def generate_cor(pallet_number):
pallet = frappe.get_doc('Pallet', pallet_number)
device_counts = get_device_counts(pallet_number)
output = io.BytesIO()
doc = SimpleDocTemplate(output, pagesize=letter, topMargin=0.75*inch, bottomMargin=0.75*inch, leftMargin=0.75*inch, rightMargin=0.75*inch)
styles = getSampleStyleSheet()
title_style = ParagraphStyle('CertTitle', parent=styles['Title'], fontSize=20, textColor=DARK_BLUE, spaceAfter=6, alignment=TA_CENTER)
body_style = ParagraphStyle('CertBody', parent=styles['Normal'], fontSize=11, spaceAfter=4)
section_style = ParagraphStyle('SectionHeader', parent=styles['Heading2'], fontSize=14, textColor=DARK_BLUE, spaceBefore=12, spaceAfter=6)
elements = []
elements.append(Paragraph('CERTIFICATE OF RECYCLING', title_style))
elements.append(Spacer(1, 6))
intro = 'Full Circle Electronics AZ, LLC (dba Westech Recyclers) certifies that the materials submitted for recycling are received and will be properly recycled in accordance with all state and federal recycling regulations and in accordance with the R2 Standard.'
elements.append(Paragraph(intro, body_style))
elements.append(Spacer(1, 8))
elements.append(Paragraph('Materials Submitted by:', section_style))
pallet_data = [
['Company:', pallet.company_name or pallet.customer_number or 'N/A'],
['Pallet Number:', pallet.pallet_number or pallet_number],
['Date Received:', str(pallet.received_date or 'N/A')],
['Weight:', str(pallet.inbound_weight or 'N/A') + ' lbs'],
['Technician:', pallet.tester or 'N/A'],
]
pallet_table = Table(pallet_data, colWidths=[1.5*inch, 4*inch])
pallet_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (0, -1), LIGHT_BLUE),
('TEXTCOLOR', (0, 0), (0, -1), DARK_BLUE),
('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, -1), 10),
('ALIGN', (0, 0), (0, -1), 'RIGHT'),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('TOPPADDING', (0, 0), (-1, -1), 4),
('BOTTOMPADDING', (0, 0), (-1, -1), 4),
]))
elements.append(pallet_table)
elements.append(Spacer(1, 12))
if device_counts:
elements.append(Paragraph('Device Summary:', section_style))
device_data = [['Device Type', 'Count']]
for dtype, count in sorted(device_counts.items()):
device_data.append([dtype or 'Unknown', str(count)])
device_table = Table(device_data, colWidths=[3*inch, 2*inch])
device_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), DARK_BLUE),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, HexColor('#F2F2F2')]),
]))
elements.append(device_table)
elements.append(Spacer(1, 12))
elements.append(HRFlowable(width='100%', thickness=1, color=DARK_BLUE, spaceBefore=12))
footer = Paragraph('Full Circle Electronics AZ, LLC | 220 S 9th St Phoenix, AZ 85034 | www.westechrecyclers.com | 602.256.7626',
ParagraphStyle('Footer', parent=styles['Normal'], fontSize=9, textColor=GRAY, alignment=TA_CENTER))
elements.append(Spacer(1, 6))
elements.append(footer)
doc.build(elements)
output.seek(0)
frappe.response.filename = 'COR_' + pallet_number + '.pdf'
frappe.response.filecontent = output.getvalue()
frappe.response.type = 'download'
frappe.response.display_content_as = 'attachment'