{'role': 'assistant', 'content': '\n\nfrom flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_file\nfrom flask_sqlalchemy import SQLAlchemy\nfrom werkzeug.security import generate_password_hash, check_password_hash\nfrom datetime import datetime\nimport random\nimport string\nimport os\nfrom io import BytesIO\nimport base64\nfrom reportlab.lib.pagesizes import letter, A4\nfrom reportlab.lib import colors\nfrom reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image\nfrom reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle\nfrom reportlab.lib.enums import TA_CENTER, TA_LEFT\nimport qrcode\nfrom PIL import Image as PILImage\n\napp = Flask(__name__)\napp.config[\'SECRET_KEY\'] = \'nexusship-secret-key-2024\'\napp.config[\'SQLALCHEMY_DATABASE_URI\'] = \'sqlite:///nexusship.db\'\napp.config[\'SQLALCHEMY_TRACK_MODIFICATIONS\'] = False\napp.config[\'MAX_CONTENT_LENGTH\'] = 16 * 1024 * 1024\n\ndb = SQLAlchemy(app)\n\n# Database Models\nclass Admin(db.Model):\n id = db.Column(db.Integer, primary_key=True)\n username = db.Column(db.String(80), unique=True, nullable=False)\n password_hash = db.Column(db.String(255), nullable=False)\n created_at = db.Column(db.DateTime, default=datetime.utcnow)\n\nclass Shipment(db.Model):\n id = db.Column(db.Integer, primary_key=True)\n tracking_number = db.Column(db.String(20), unique=True, nullable=False)\n shipper_name = db.Column(db.String(100), nullable=False)\n shipper_address = db.Column(db.Text, nullable=False)\n receiver_name = db.Column(db.String(100), nullable=False)\n receiver_address = db.Column(db.Text, nullable=False)\n shipment_date = db.Column(db.DateTime, nullable=False)\n delivery_date = db.Column(db.DateTime, nullable=True)\n status = db.Column(db.String(50), default=\'Processing\')\n weight = db.Column(db.Float, default=0.0)\n service_type = db.Column(db.String(50), default=\'Standard\')\n created_at = db.Column(db.DateTime, default=datetime.utcnow)\n updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)\n\nclass TrackingHistory(db.Model):\n id = db.Column(db.Integer, primary_key=True)\n tracking_number = db.Column(db.String(20), db.ForeignKey(\'shipment.tracking_number\'), nullable=False)\n status = db.Column(db.String(50), nullable=False)\n location = db.Column(db.String(200), nullable=False)\n description = db.Column(db.Text, nullable=True)\n timestamp = db.Column(db.DateTime, default=datetime.utcnow)\n backcode = db.Column(db.String(50), nullable=True)\n\n# Initialize database\nwith app.app_context():\n db.create_all()\n \n # Create default admin if not exists\n admin = Admin.query.filter_by(username=\'admin\').first()\n if not admin:\n admin = Admin(\n username=\'admin\',\n password_hash=generate_password_hash(\'Adedapo1997$\')\n )\n db.session.add(admin)\n db.session.commit()\n\n# Helper functions\ndef generate_tracking_number():\n """Generate a unique tracking number"""\n while True:\n # Format: NS-XXXXXXXX-XXXX (NS for NexusShip)\n num1 = \'\'.join(random.choices(string.digits, k=8))\n num2 = \'\'.join(random.choices(string.digits, k=4))\n tracking_num = f"NS-{num1}-{num2}"\n if not Shipment.query.filter_by(tracking_number=tracking_num).first():\n return tracking_num\n\ndef generate_backcode(status):\n """Generate backcode based on status"""\n codes = {\n \'Processing\': \'PROC\',\n \'In Transit\': \'TRNS\',\n \'Out for Delivery\': \'OUTD\',\n \'Delivered\': \'DLVR\',\n \'On Hold\': \'HOLD\',\n \'Exception\': \'EXCP\',\n \'Delayed\': \'DLYD\'\n }\n prefix = codes.get(status, \'UNKN\')\n return f"{prefix}-{datetime.utcnow().strftime(\'%Y%m%d\')}-{random.randint(1000, 9999)}"\n\n# Routes\n@app.route(\'/\')\ndef index():\n return render_template(\'index.html\')\n\n@app.route(\'/about\')\ndef about():\n return render_template(\'about.html\')\n\n@app.route(\'/contact\')\ndef contact():\n return render_template(\'contact.html\')\n\n@app.route(\'/track\')\ndef track():\n return render_template(\'track.html\')\n\n@app.route(\'/admin\')\ndef admin():\n if \'admin_logged_in\' not in session:\n return redirect(url_for(\'admin_login\'))\n return render_template(\'admin.html\')\n\n@app.route(\'/admin/login\', methods=[\'GET\', \'POST\'])\ndef admin_login():\n if request.method == \'POST\':\n username = request.form.get(\'username\')\n password = request.form.get(\'password\')\n \n admin = Admin.query.filter_by(username=username).first()\n if admin and check_password_hash(admin.password_hash, password):\n session[\'admin_logged_in\'] = True\n session[\'admin_username\'] = username\n return redirect(url_for(\'admin\'))\n else:\n return render_template(\'admin_login.html\', error=\'Invalid credentials\')\n \n return render_template(\'admin_login.html\')\n\n@app.route(\'/admin/logout\')\ndef admin_logout():\n session.pop(\'admin_logged_in\', None)\n session.pop(\'admin_username\', None)\n return redirect(url_for(\'admin_login\'))\n\n# API Routes\n@app.route(\'/api/track\', methods=[\'POST\'])\ndef api_track():\n data = request.json\n tracking_number = data.get(\'tracking_number\')\n \n shipment = Shipment.query.filter_by(tracking_number=tracking_number).first()\n \n if not shipment:\n return jsonify({\'error\': \'Tracking number not found\'}), 404\n \n # Get tracking history\n history = TrackingHistory.query.filter_by(\n tracking_number=tracking_number\n ).order_by(TrackingHistory.timestamp.desc()).all()\n \n history_data = []\n for h in history:\n history_data.append({\n \'status\': h.status,\n \'location\': h.location,\n \'description\': h.description,\n \'timestamp\': h.timestamp.strftime(\'%Y-%m-%d %H:%M:%S\'),\n \'backcode\': h.backcode\n })\n \n return jsonify({\n \'tracking_number\': shipment.tracking_number,\n \'shipper_name\': shipment.shipper_name,\n \'shipper_address\': shipment.shipper_address,\n \'receiver_name\': shipment.receiver_name,\n \'receiver_address\': shipment.receiver_address,\n \'shipment_date\': shipment.shipment_date.strftime(\'%Y-%m-%d\'),\n \'delivery_date\': shipment.delivery_date.strftime(\'%Y-%m-%d\') if shipment.delivery_date else None,\n \'status\': shipment.status,\n \'weight\': shipment.weight,\n \'service_type\': shipment.service_type,\n \'history\': history_data\n })\n\n@app.route(\'/api/admin/generate-tracking\', methods=[\'POST\'])\ndef api_generate_tracking():\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n count = request.json.get(\'count\', 300)\n tracking_numbers = []\n \n for _ in range(count):\n tracking_num = generate_tracking_number()\n tracking_numbers.append(tracking_num)\n \n return jsonify({\'tracking_numbers\': tracking_numbers})\n\n@app.route(\'/api/admin/shipments\', methods=[\'GET\'])\ndef api_get_shipments():\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n shipments = Shipment.query.order_by(Shipment.created_at.desc()).all()\n shipments_data = []\n \n for s in shipments:\n shipments_data.append({\n \'id\': s.id,\n \'tracking_number\': s.tracking_number,\n \'shipper_name\': s.shipper_name,\n \'receiver_name\': s.receiver_name,\n \'status\': s.status,\n \'shipment_date\': s.shipment_date.strftime(\'%Y-%m-%d\'),\n \'delivery_date\': s.delivery_date.strftime(\'%Y-%m-%d\') if s.delivery_date else None\n })\n \n return jsonify({\'shipments\': shipments_data})\n\n@app.route(\'/api/admin/shipment\', methods=[\'POST\'])\ndef api_create_shipment():\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n data = request.json\n \n # Validate tracking number exists\n if Shipment.query.filter_by(tracking_number=data[\'tracking_number\']).first():\n return jsonify({\'error\': \'Tracking number already in use\'}), 400\n \n # Parse dates\n shipment_date = datetime.strptime(data[\'shipment_date\'], \'%Y-%m-%d\')\n delivery_date = None\n if data.get(\'delivery_date\'):\n delivery_date = datetime.strptime(data[\'delivery_date\'], \'%Y-%m-%d\')\n \n shipment = Shipment(\n tracking_number=data[\'tracking_number\'],\n shipper_name=data[\'shipper_name\'],\n shipper_address=data[\'shipper_address\'],\n receiver_name=data[\'receiver_name\'],\n receiver_address=data[\'receiver_address\'],\n shipment_date=shipment_date,\n delivery_date=delivery_date,\n status=data.get(\'status\', \'Processing\'),\n weight=float(data.get(\'weight\', 0)),\n service_type=data.get(\'service_type\', \'Standard\')\n )\n \n db.session.add(shipment)\n db.session.commit()\n \n # Add initial tracking history\n initial_history = TrackingHistory(\n tracking_number=data[\'tracking_number\'],\n status=data.get(\'status\', \'Processing\'),\n location=data.get(\'location\', \'Origin Facility\'),\n description=f"Shipment created and processed",\n backcode=generate_backcode(data.get(\'status\', \'Processing\'))\n )\n db.session.add(initial_history)\n db.session.commit()\n \n return jsonify({\'success\': True, \'tracking_number\': shipment.tracking_number})\n\n@app.route(\'/api/admin/shipment/\', methods=[\'PUT\'])\ndef api_update_shipment(shipment_id):\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n data = request.json\n shipment = Shipment.query.get_or_404(shipment_id)\n \n # Update basic info\n if \'shipper_name\' in data:\n shipment.shipper_name = data[\'shipper_name\']\n if \'shipper_address\' in data:\n shipment.shipper_address = data[\'shipper_address\']\n if \'receiver_name\' in data:\n shipment.receiver_name = data[\'receiver_name\']\n if \'receiver_address\' in data:\n shipment.receiver_address = data[\'receiver_address\']\n \n if \'shipment_date\' in data:\n shipment.shipment_date = datetime.strptime(data[\'shipment_date\'], \'%Y-%m-%d\')\n if \'delivery_date\' in data:\n if data[\'delivery_date\']:\n shipment.delivery_date = datetime.strptime(data[\'delivery_date\'], \'%Y-%m-%d\')\n else:\n shipment.delivery_date = None\n \n if \'status\' in data:\n shipment.status = data[\'status\']\n \n # Add tracking history entry\n if \'location\' in data:\n new_history = TrackingHistory(\n tracking_number=shipment.tracking_number,\n status=data[\'status\'],\n location=data[\'location\'],\n description=data.get(\'description\', f"Status updated to {data[\'status\']}"),\n backcode=generate_backcode(data[\'status\'])\n )\n db.session.add(new_history)\n \n if \'weight\' in data:\n shipment.weight = float(data[\'weight\'])\n if \'service_type\' in data:\n shipment.service_type = data[\'service_type\']\n \n shipment.updated_at = datetime.utcnow()\n db.session.commit()\n \n return jsonify({\'success\': True})\n\n@app.route(\'/api/admin/shipment/\', methods=[\'DELETE\'])\ndef api_delete_shipment(shipment_id):\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n shipment = Shipment.query.get_or_404(shipment_id)\n \n # Delete tracking history first\n TrackingHistory.query.filter_by(tracking_number=shipment.tracking_number).delete()\n \n db.session.delete(shipment)\n db.session.commit()\n \n return jsonify({\'success\': True})\n\n@app.route(\'/api/admin/bulk-update-status\', methods=[\'POST\'])\ndef api_bulk_update_status():\n if \'admin_logged_in\' not in session:\n return jsonify({\'error\': \'Unauthorized\'}), 401\n \n data = request.json\n tracking_numbers = data.get(\'tracking_numbers\', [])\n status = data.get(\'status\')\n location = data.get(\'location\', \'Updated\')\n description = data.get(\'description\', f"Status updated to {status}")\n \n for tracking_num in tracking_numbers:\n shipment = Shipment.query.filter_by(tracking_number=tracking_num).first()\n if shipment:\n shipment.status = status\n \n # Add tracking history\n new_history = TrackingHistory(\n tracking_number=tracking_num,\n status=status,\n location=location,\n description=description,\n backcode=generate_backcode(status)\n )\n db.session.add(new_history)\n \n db.session.commit()\n \n return jsonify({\'success\': True, \'updated\': len(tracking_numbers)})\n\n@app.route(\'/api/receipt/\')\ndef api_receipt(tracking_number):\n shipment = Shipment.query.filter_by(tracking_number=tracking_number).first()\n \n if not shipment:\n return jsonify({\'error\': \'Tracking number not found\'}), 404\n \n # Get tracking history\n history = TrackingHistory.query.filter_by(\n tracking_number=tracking_number\n ).order_by(TrackingHistory.timestamp.desc()).all()\n \n history_data = []\n for h in history:\n history_data.append({\n \'status\': h.status,\n \'location\': h.location,\n \'description\': h.description,\n \'timestamp\': h.timestamp.strftime(\'%Y-%m-%d %H:%M:%S\'),\n \'backcode\': h.backcode\n })\n \n return jsonify({\n \'tracking_number\': shipment.tracking_number,\n \'shipper_name\': shipment.shipper_name,\n \'shipper_address\': shipment.shipper_address,\n \'receiver_name\': shipment.receiver_name,\n \'receiver_address\': shipment.receiver_address,\n \'shipment_date\': shipment.shipment_date.strftime(\'%Y-%m-%d\'),\n \'delivery_date\': shipment.delivery_date.strftime(\'%Y-%m-%d\') if shipment.delivery_date else None,\n \'status\': shipment.status,\n \'weight\': shipment.weight,\n \'service_type\': shipment.service_type,\n \'history\': history_data,\n \'created_at\': shipment.created_at.strftime(\'%Y-%m-%d %H:%M:%S\')\n })\n\n@app.route(\'/api/receipt/pdf/\')\ndef api_receipt_pdf(tracking_number):\n shipment = Shipment.query.filter_by(tracking_number=tracking_number).first()\n \n if not shipment:\n return "Shipment not found", 404\n \n # Get tracking history\n history = TrackingHistory.query.filter_by(\n tracking_number=tracking_number\n ).order_by(TrackingHistory.timestamp.desc()).all()\n \n # Create PDF\n buffer = BytesIO()\n doc = SimpleDocTemplate(buffer, pagesize=A4)\n elements = []\n styles = getSampleStyleSheet()\n \n # Custom styles\n title_style = ParagraphStyle(\n \'CustomTitle\',\n parent=styles[\'Heading1\'],\n fontSize=24,\n textColor=colors.HexColor(\'#4D148C\'),\n alignment=TA_CENTER,\n spaceAfter=30\n )\n \n # Header\n elements.append(Paragraph("NexusShip", title_style))\n elements.append(Paragraph("Shipping Receipt", styles[\'Heading2\']))\n elements.append(Spacer(1, 20))\n \n # Generate QR Code\n qr = qrcode.QRCode(version=1, box_size=10, border=5)\n qr.add_data(shipment.tracking_number)\n qr.make(fit=True)\n qr_image = qr.make_image(fill_color="black", back_color="white")\n \n # Save QR code to temporary buffer\n qr_buffer = BytesIO()\n qr_image.save(qr_buffer, format=\'PNG\')\n qr_buffer.seek(0)\n \n # Add tracking number and QR code\n tracking_data = [\n [\'Tracking Number:\', shipment.tracking_number],\n [\'Status:\', shipment.status],\n [\'Service Type:\', shipment.service_type]\n ]\n \n tracking_table = Table(tracking_data, colWidths=[150, 300])\n tracking_table.setStyle(TableStyle([\n (\'BACKGROUND\', (0, 0), (0, 2), colors.HexColor(\'#4D148C\')),\n (\'TEXTCOLOR\', (0, 0), (0, 2), colors.whitesmoke),\n (\'ALIGN\', (0, 0), (-1, -1), \'LEFT\'),\n (\'FONTNAME\', (0, 0), (-1, -1), \'Helvetica\'),\n (\'FONTSIZE\', (0, 0), (-1, -1), 12),\n (\'BOTTOMPADDING\', (0, 0), (-1, -1), 12),\n (\'BACKGROUND\', (1, 0), (1, 2), colors.beige),\n (\'GRID\', (0, 0), (-1, -1), 1, colors.black)\n ]))\n \n elements.append(tracking_table)\n elements.append(Spacer(1, 20))\n \n # Shipper and Receiver Information\n elements.append(Paragraph("Shipper Information", styles[\'Heading3\']))\n shipper_data = [\n [\'Name:\', shipment.shipper_name],\n [\'Address:\', shipment.shipper_address.replace(\'\\n\', \', \')]\n ]\n \n shipper_table = Table(shipper_data, colWidths=[100, 350])\n shipper_table.setStyle(TableStyle([\n (\'BACKGROUND\', (0, 0), (0, -1), colors.HexColor(\'#666666\')),\n (\'TEXTCOLOR\', (0, 0), (0, -1), colors.whitesmoke),\n (\'ALIGN\', (0, 0), (-1, -1), \'LEFT\'),\n (\'FONTNAME\', (0, 0), (-1, -1), \'Helvetica\'),\n (\'FONTSIZE\', (0, 0), (-1, -1), 10),\n (\'BOTTOMPADDING\', (0, 0), (-1, -1), 10),\n (\'BACKGROUND\', (1, 0), (1, -1), colors.lightgrey),\n (\'GRID\', (0, 0), (-1, -1), 1, colors.black)\n ]))\n \n elements.append(shipper_table)\n elements.append(Spacer(1, 20))\n \n elements.append(Paragraph("Receiver Information", styles[\'Heading3\']))\n receiver_data = [\n [\'Name:\', shipment.receiver_name],\n [\'Address:\', shipment.receiver_address.replace(\'\\n\', \', \')]\n ]\n \n receiver_table = Table(receiver_data, colWidths=[100, 350])\n receiver_table.setStyle(TableStyle([\n (\'BACKGROUND\', (0, 0), (0, -1), colors.HexColor(\'#666666\')),\n (\'TEXTCOLOR\', (0, 0), (0, -1), colors.whitesmoke),\n (\'ALIGN\', (0, 0), (-1, -1), \'LEFT\'),\n (\'FONTNAME\', (0, 0), (-1, -1), \'Helvetica\'),\n (\'FONTSIZE\', (0, 0), (-1, -1), 10),\n (\'BOTTOMPADDING\', (0, 0), (-1, -1), 10),\n (\'BACKGROUND\', (1, 0), (1, -1), colors.lightgrey),\n (\'GRID\', (0, 0), (-1, -1), 1, colors.black)\n ]))\n \n elements.append(receiver_table)\n elements.append(Spacer(1, 20))\n \n # Dates\n dates_data = [\n [\'Shipment Date:\', shipment.shipment_date.strftime(\'%Y-%m-%d\')],\n [\'Expected Delivery:\', shipment.delivery_date.strftime(\'%Y-%m-%d\') if shipment.delivery_date else \'Pending\']\n ]\n \n dates_table = Table(dates_data, colWidths=[150, 300])\n dates_table.setStyle(TableStyle([\n (\'BACKGROUND\', (0, 0), (0, 1), colors.HexColor(\'#4D148C\')),\n (\'TEXTCOLOR\', (0, 0), (0, 1), colors.whitesmoke),\n (\'ALIGN\', (0, 0), (-1, -1), \'LEFT\'),\n (\'FONTNAME\', (0, 0), (-1, -1), \'Helvetica\'),\n (\'FONTSIZE\', (0, 0), (-1, -1), 12),\n (\'BOTTOMPADDING\', (0, 0), (-1, -1), 12),\n (\'BACKGROUND\', (1, 0), (1, 1), colors.beige),\n (\'GRID\', (0, 0), (-1, -1), 1, colors.black)\n ]))\n \n elements.append(dates_table)\n elements.append(Spacer(1, 20))\n \n # Tracking History\n elements.append(Paragraph("Tracking History", styles[\'Heading3\']))\n \n history_rows = [[\'Status\', \'Location\', \'Description\', \'Date/Time\', \'Backcode\']]\n for h in history:\n history_rows.append([\n h.status,\n h.location,\n h.description,\n h.timestamp.strftime(\'%Y-%m-%d %H:%M\'),\n h.backcode\n ])\n \n history_table = Table(history_rows, colWidths=[80, 120, 150, 120, 80])\n history_table.setStyle(TableStyle([\n (\'BACKGROUND\', (0, 0), (-1, 0), colors.HexColor(\'#4D148C\')),\n (\'TEXTCOLOR\', (0, 0), (-1, 0), colors.whitesmoke),\n (\'ALIGN\', (0, 0), (-1, -1), \'LEFT\'),\n (\'FONTNAME\', (0, 0), (-1, -1), \'Helvetica\'),\n (\'FONTSIZE\', (0, 0), (-1, -1), 9),\n (\'TOPPADDING\', (0, 0), (-1, -1), 8),\n (\'BOTTOMPADDING\', (0, 0), (-1, -1), 8),\n (\'GRID\', (0, 0), (-1, -1), 1, colors.black),\n (\'ROWBACKGROUNDS\', (0, 1), (-1, -1), [colors.white, colors.lightgrey])\n ]))\n \n elements.append(history_table)\n elements.append(Spacer(1, 30))\n \n # Footer\n footer_text = "Thank you for choosing NexusShip. For inquiries, contact us at support@nexusship.com"\n elements.append(Paragraph(footer_text, ParagraphStyle(\'Footer\', alignment=TA_CENTER, fontSize=10)))\n \n # Build PDF\n doc.build(elements)\n buffer.seek(0)\n \n return send_file(\n buffer,\n as_attachment=True,\n download_name=f\'receipt_{tracking_number}.pdf\',\n mimetype=\'application/pdf\'\n )\n\nif __name__ == \'__main__\':\n app.run(debug=True, host=\'0.0.0.0\', port=5000)\n\n'}