Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import random | |
| import string | |
| import datetime | |
| from reportlab.lib.pagesizes import A4 | |
| from reportlab.lib import colors | |
| from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle | |
| from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet | |
| from reportlab.lib.units import cm | |
| # Daftar produk dan kategori | |
| categories = { | |
| "Kategori A": ["Produk A1", "Produk A2", "Produk A3", "Produk A4", "Produk A5", "Produk A6"], | |
| "Kategori B": ["Produk B1", "Produk B2", "Produk B3", "Produk B4", "Produk B5", "Produk B6"], | |
| "Kategori C": ["Produk C1", "Produk C2", "Produk C3", "Produk C4", "Produk C5", "Produk C6"], | |
| "Kategori D": ["Produk D1", "Produk D2", "Produk D3", "Produk D4", "Produk D5", "Produk D6"] | |
| } | |
| # Fungsi untuk membuat dokumen PDF | |
| def create_pdf(data, filename): | |
| doc = SimpleDocTemplate(filename, pagesize=A4, rightMargin=2*cm, leftMargin=2*cm, topMargin=2*cm, bottomMargin=2*cm) | |
| styles = getSampleStyleSheet() | |
| elements = [] | |
| # Gaya teks | |
| title_style = ParagraphStyle(name='Title', fontSize=16, alignment=1, spaceAfter=12) | |
| normal_style = ParagraphStyle(name='Normal', fontSize=10, spaceAfter=8) | |
| bold_style = ParagraphStyle(name='Bold', fontSize=10, fontName='Helvetica-Bold', spaceAfter=8) | |
| # Header | |
| elements.append(Paragraph("Dokumen Penawaran", title_style)) | |
| elements.append(Paragraph("PT. Contoh Perusahaan", normal_style)) | |
| elements.append(Paragraph("Jl. Contoh Alamat No. 123", normal_style)) | |
| elements.append(Spacer(1, 0.5*cm)) | |
| # Kepada Yth. | |
| elements.append(Paragraph(f"Kepada Yth.", normal_style)) | |
| elements.append(Paragraph(f"{data['nama_prospek']}", bold_style)) | |
| elements.append(Paragraph(f"{data['alamat_prospek']}", normal_style)) | |
| elements.append(Paragraph(f"Jenis Prospek: {data['jenis_prospek']}", normal_style)) | |
| elements.append(Spacer(1, 0.5*cm)) | |
| # Tanggal | |
| elements.append(Paragraph(f"Tanggal: {data['tanggal']}", normal_style)) | |
| elements.append(Spacer(1, 0.5*cm)) | |
| # Tabel Produk | |
| elements.append(Paragraph("Daftar Produk yang Ditawarkan:", bold_style)) | |
| # Data tabel | |
| table_data = [["Nama Produk", "Jumlah", "Harga (Rp)", "Total (Rp)"]] | |
| sub_total = 0 | |
| for p in data['produk']: | |
| total = p['jumlah'] * float(p['harga']) | |
| sub_total += total | |
| table_data.append([p['nama'], str(p['jumlah']), f"{p['harga']:,}", f"{total:,}"]) | |
| # Hitung diskon dan grand total | |
| if 'diskon' in data and data['diskon']: | |
| diskon_percent = float(data['diskon']) | |
| diskon_amount = (diskon_percent / 100) * sub_total | |
| grand_total = sub_total - diskon_amount | |
| else: | |
| diskon_percent = 0 | |
| diskon_amount = 0 | |
| grand_total = sub_total | |
| # Tambahkan baris sub-total, diskon, dan grand total | |
| table_data.append(["", "", "Sub-Total", f"{sub_total:,}"]) | |
| if diskon_percent > 0: | |
| table_data.append(["", "", f"Diskon ({diskon_percent}%)", f"-{diskon_amount:,}"]) | |
| table_data.append(["", "", "Grand Total", f"{grand_total:,}"]) | |
| # Buat tabel | |
| table = Table(table_data, colWidths=[6*cm, 2*cm, 3*cm, 3*cm]) | |
| table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (-1, 0), colors.grey), | |
| ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), | |
| ('ALIGN', (0, 0), (-1, -1), 'CENTER'), | |
| ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), | |
| ('FONTSIZE', (0, 0), (-1, -1), 10), | |
| ('BOTTOMPADDING', (0, 0), (-1, 0), 10), | |
| ('BACKGROUND', (0, 1), (-1, -3), colors.beige), | |
| ('GRID', (0, 0), (-1, -1), 1, colors.black), | |
| ('SPAN', (0, -2), (1, -2)), # Span sub-total | |
| ('SPAN', (0, -1), (1, -1)), # Span grand total | |
| ('ALIGN', (2, -2), (3, -1), 'CENTER'), # Align right for totals | |
| ])) | |
| if diskon_percent > 0: | |
| table.setStyle(TableStyle([ | |
| ('SPAN', (0, -3), (1, -3)), # Span diskon | |
| ])) | |
| elements.append(table) | |
| elements.append(Spacer(1, 0.5*cm)) | |
| # Syarat dan Ketentuan | |
| syarat_text = f"Syarat dan Ketentuan:<br/>{data['syarat']}" if 'syarat' in data else "Syarat dan Ketentuan: Tidak ada" | |
| elements.append(Paragraph(syarat_text, normal_style)) | |
| elements.append(Spacer(1, 0.5*cm)) | |
| # Tanda Tangan | |
| elements.append(Paragraph("Hormat kami,", normal_style)) | |
| elements.append(Paragraph("PT. Contoh Perusahaan", normal_style)) | |
| # Build PDF | |
| doc.build(elements) | |
| return filename | |
| # Fungsi untuk memproses input dan membuat penawaran | |
| def buat_penawaran(nama_prospek, alamat_prospek, jenis_prospek, produk_dipilih, jumlah_produk, harga_produk, diskon, tanggal, syarat): | |
| data = { | |
| 'nama_prospek': nama_prospek if nama_prospek else "Prospek Tanpa Nama", | |
| 'alamat_prospek': alamat_prospek if alamat_prospek else "Alamat Tidak Diketahui", | |
| 'jenis_prospek': jenis_prospek if jenis_prospek else "Individu", | |
| 'tanggal': tanggal if tanggal else datetime.date.today().strftime("%Y-%m-%d"), | |
| 'produk': [] | |
| } | |
| # Proses produk | |
| if produk_dipilih and jumlah_produk and harga_produk: | |
| try: | |
| jumlah_list = [int(x.strip()) for x in jumlah_produk.split(",") if x.strip()] | |
| harga_list = [int(x.strip()) for x in harga_produk.split(",") if x.strip()] | |
| for i, p in enumerate(produk_dipilih): | |
| j = jumlah_list[i] if i < len(jumlah_list) else 1 | |
| h = harga_list[i] if i < len(harga_list) else 100000 | |
| data['produk'].append({'nama': p, 'jumlah': j, 'harga': h}) | |
| except ValueError: | |
| data['produk'].append({'nama': "Produk Contoh", 'jumlah': 1, 'harga': 100000}) | |
| warning = "Peringatan: Format jumlah atau harga produk salah. Diganti dengan data contoh." | |
| else: | |
| data['produk'].append({'nama': "Produk Contoh", 'jumlah': 1, 'harga': 100000}) | |
| if diskon: | |
| try: | |
| data['diskon'] = float(diskon) | |
| except ValueError: | |
| data['diskon'] = 0 | |
| if syarat: | |
| data['syarat'] = syarat | |
| # Validasi data | |
| missing_data = [] | |
| if not nama_prospek: | |
| missing_data.append("Nama Prospek") | |
| if not alamat_prospek: | |
| missing_data.append("Alamat Prospek") | |
| if not jenis_prospek: | |
| missing_data.append("Jenis Prospek") | |
| if not tanggal: | |
| missing_data.append("Tanggal") | |
| if not produk_dipilih or not jumlah_produk or not harga_produk: | |
| missing_data.append("Produk, Jumlah, atau Harga") | |
| warning = "" | |
| if missing_data: | |
| warning = "Peringatan: Data berikut kurang dan telah diisi dengan asumsi: " + ", ".join(missing_data) + ". Silakan lengkapi data jika perlu." | |
| # Buat file PDF | |
| filename = ''.join(random.choices(string.ascii_letters + string.digits, k=10)) + ".pdf" | |
| pdf_file = create_pdf(data, filename) | |
| return pdf_file, warning | |
| # Interface Gradio | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Aplikasi Pembuatan Dokumen Penawaran") | |
| with gr.Row(): | |
| nama_prospek = gr.Textbox(label="Nama Prospek") | |
| alamat_prospek = gr.Textbox(label="Alamat Prospek") | |
| jenis_prospek = gr.Dropdown(choices=["Individu", "Perusahaan", "Kafe"], label="Jenis Prospek") | |
| with gr.Row(): | |
| tanggal = gr.Textbox(label="Tanggal Penawaran (YYYY-MM-DD)") | |
| with gr.Row(): | |
| produk_dipilih = gr.CheckboxGroup(choices=[p for cat in categories.values() for p in cat], label="Pilih Produk") | |
| jumlah_produk = gr.Textbox(label="Jumlah Produk (pisahkan dengan koma)") | |
| harga_produk = gr.Textbox(label="Harga per Produk (Rp, pisahkan dengan koma)") | |
| with gr.Row(): | |
| diskon = gr.Textbox(label="Diskon (%)") | |
| syarat = gr.Textbox(label="Syarat dan Ketentuan") | |
| submit_button = gr.Button("Buat Penawaran") | |
| output_file = gr.File(label="Download Dokumen Penawaran (PDF)") | |
| warning_text = gr.Textbox(label="Peringatan") | |
| submit_button.click( | |
| buat_penawaran, | |
| inputs=[nama_prospek, alamat_prospek, jenis_prospek, produk_dipilih, jumlah_produk, harga_produk, diskon, tanggal, syarat], | |
| outputs=[output_file, warning_text] | |
| ) | |
| demo.launch() |