File size: 9,085 Bytes
559ff90
7c6188a
559ff90
7c6188a
5d377bc
559ff90
 
5d377bc
559ff90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d377bc
559ff90
 
 
 
5d377bc
559ff90
 
5d377bc
559ff90
 
 
 
 
 
 
 
 
5d377bc
559ff90
 
 
5d377bc
7c6188a
559ff90
 
 
 
 
5d377bc
559ff90
 
 
5d377bc
559ff90
5d377bc
 
 
7c6188a
5d377bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7c6188a
559ff90
 
 
5d377bc
 
 
 
 
 
 
 
 
 
 
 
 
559ff90
5d377bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559ff90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d377bc
559ff90
 
 
 
 
 
 
 
 
 
 
 
 
5d377bc
559ff90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7c6188a
5d377bc
559ff90
 
 
 
5d377bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
import os
import streamlit as st
from openai import OpenAI

# ===== CONFIG =====
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") or st.secrets.get("OPENAI_API_KEY", None)

st.set_page_config(page_title="Procelevate AI Agent", page_icon="πŸ€–", layout="wide")
st.title("πŸ€– Procelevate Agent Suite")

if not OPENAI_API_KEY:
    st.warning("⚠️ OPENAI_API_KEY not found. Set it in the Space secrets.")
client = OpenAI(api_key=OPENAI_API_KEY) if OPENAI_API_KEY else None


def call_llm(system_prompt: str, user_prompt: str) -> str:
    if client is None:
        return "❗OPENAI_API_KEY not set."
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
        temperature=0.25,
    )
    return resp.choices[0].message.content


# ===== EXISTING FUNCTIONS =====
def generate_po(buyer_name, buyer_address, supplier_name, supplier_email, items_text, payment_terms, notes):
    system_prompt = """You are a Purchase Order (PO) generation assistant for Procelevate.
Output in markdown with headings, line-item table, and totals. Assume 18% tax if missing."""
    user_prompt = f"""
Buyer:
- Name: {buyer_name}
- Address: {buyer_address}

Supplier:
- Name: {supplier_name}
- Email: {supplier_email}

Line Items:
{items_text}

Payment Terms: {payment_terms}
Notes: {notes}
"""
    return call_llm(system_prompt, user_prompt)


def generate_email_reply(incoming_email, reply_goal, tone):
    system_prompt = """You are an AI email responder for Procelevate Consulting & Academy.
Write a concise reply in the requested tone. End with 'Regards, Procelevate Team'."""
    user_prompt = f"""
Incoming email:
\"\"\"{incoming_email}\"\"\"
Goal: {reply_goal}
Tone: {tone}
"""
    return call_llm(system_prompt, user_prompt)


# ===== NEW: QUOTATION β†’ PR β†’ PO PIPELINE =====

def extract_text_from_upload(uploaded_file):
    # simplest path: handle text files directly
    if uploaded_file is None:
        return ""
    if uploaded_file.type == "text/plain":
        return uploaded_file.read().decode("utf-8")

    # for PDFs we need a parser; if pdfplumber not installed, just say so
    if uploaded_file.type == "application/pdf":
        try:
            import pdfplumber
            text_parts = []
            with pdfplumber.open(uploaded_file) as pdf:
                for page in pdf.pages:
                    text_parts.append(page.extract_text() or "")
            return "\n".join(text_parts)
        except Exception as e:
            return f"PDF uploaded but could not parse: {e}"

    # fallback
    return uploaded_file.read().decode("utf-8", errors="ignore")


def create_pr_from_quotation(quotation_text, buyer_org):
    system_prompt = """You are a purchasing assistant. Given a supplier quotation text, extract:
- supplier_name
- line_items (description, qty, unit_price if present)
- currency (guess if missing)
Return a clean JSON-like structure representing a Purchase Requisition (PR) for internal approval."""
    user_prompt = f"""
Organisation: {buyer_org}
Quotation text:
\"\"\"{quotation_text}\"\"\"

Return PR as JSON with keys:
pr_title, supplier_name, currency, line_items, total_if_available.
"""
    return call_llm(system_prompt, user_prompt)


def create_approval_email(pr_json_text, approver_email="approver@example.com"):
    system_prompt = """You are an approval workflow assistant. Write an approval request email for a PR.
Email must include: PR title, supplier, amount, and a clear approve/reject instruction.
Don't actually send it, just draft."""
    user_prompt = f"""
PR details (JSON):
{pr_json_text}

Approver email: {approver_email}
Write the approval email.
"""
    return call_llm(system_prompt, user_prompt)


def create_po_from_pr(pr_json_text, buyer_name, buyer_address, supplier_email):
    system_prompt = """You are a PO generator. Convert the approved PR (JSON) into a Purchase Order in markdown.
Include buyer, supplier, line items table, totals, and payment terms (assume Net 30)."""
    user_prompt = f"""
Buyer name: {buyer_name}
Buyer address: {buyer_address}
Supplier email: {supplier_email}
PR JSON:
{pr_json_text}
"""
    return call_llm(system_prompt, user_prompt)


def create_supplier_email(po_markdown, supplier_email):
    system_prompt = """You are a business email writer. Write an email to supplier attaching/sending PO details.
Keep it formal, short. Mention PO number if present."""
    user_prompt = f"""
Supplier: {supplier_email}
PO content:
{po_markdown}
"""
    return call_llm(system_prompt, user_prompt)


# ===== UI TABS =====
tab1, tab2, tab3 = st.tabs(["πŸ“„ PO Automation", "πŸ“§ Email Responder", "πŸ“¦ Quotation β†’ PR β†’ PO"])

# --- TAB 1: Existing PO form ---
with tab1:
    st.subheader("πŸ“„ Generate Purchase Order")
    col1, col2 = st.columns(2)
    with col1:
        buyer_name = st.text_input("Buyer Name", value="Procelevate Consulting")
        buyer_address = st.text_area("Buyer Address", value="Bengaluru, Karnataka, India", height=80)
        payment_terms = st.text_input("Payment Terms", value="Net 30 days")
    with col2:
        supplier_name = st.text_input("Supplier Name", value="")
        supplier_email = st.text_input("Supplier Email", value="")
        notes = st.text_area("Additional Notes", value="Please deliver services as per agreed SOW.", height=80)

    items_text = st.text_area(
        "Line Items (one per line)",
        value="1. AI/ML Bootcamp Seats, Qty 10, Unit Price 2999\n2. Consulting Hours, Qty 5, Unit Price 1500",
        height=120
    )

    if st.button("Generate PO", key="gen_po_basic"):
        po_md = generate_po(
            buyer_name,
            buyer_address,
            supplier_name,
            supplier_email,
            items_text,
            payment_terms,
            notes
        )
        st.markdown("---")
        st.markdown("### βœ… Generated PO")
        st.markdown(po_md)

# --- TAB 2: Email responder ---
with tab2:
    st.subheader("πŸ“§ Generate Email Reply")
    incoming_email = st.text_area(
        "Incoming email",
        value="Hi Mahesh, we are interested in your Smart Daycare Suite. Can you share pricing and a demo slot?",
        height=140
    )
    reply_goal = st.text_input(
        "What should the reply do?",
        value="Acknowledge, share that we have multiple AI/ML modules, and propose 30-min demo."
    )
    tone = st.selectbox(
        "Tone",
        options=["Professional", "Friendly", "Formal-Client", "Follow-up/Reminder"],
        index=0
    )

    if st.button("Generate Reply", key="gen_reply"):
        reply_text = generate_email_reply(incoming_email, reply_goal, tone)
        st.markdown("---")
        st.markdown("### βœ… Reply Email")
        st.markdown(reply_text)

# --- TAB 3: Quotation β†’ PR β†’ PO ---
with tab3:
    st.subheader("πŸ“¦ Quotation β†’ PR β†’ PO")
    st.write("Upload supplier quotation, let the model draft PR, generate approval mail, and convert to PO after approval.")

    quotation_file = st.file_uploader("Upload quotation (PDF or .txt)", type=["pdf", "txt"])
    buyer_org = st.text_input("Buyer Org / Company", value="Procelevate Consulting")
    supplier_email_q = st.text_input("Supplier Email (for final PO)", value="supplier@example.com")
    buyer_address_q = st.text_input("Buyer Address", value="Bengaluru, Karnataka, India")

    if st.button("1️⃣ Extract β†’ Create PR"):
        quotation_text = extract_text_from_upload(quotation_file)
        st.markdown("**Extracted text (preview):**")
        st.code(quotation_text[:800] or "No text extracted.", language="text")

        pr_json_text = create_pr_from_quotation(quotation_text, buyer_org)
        st.markdown("### βœ… Draft PR (JSON-like)")
        st.code(pr_json_text, language="json")

        st.session_state["latest_pr"] = pr_json_text
        st.success("PR drafted. Now generate approval email below.")

    if "latest_pr" in st.session_state:
        if st.button("2️⃣ Generate Approval Email"):
            approval_email = create_approval_email(st.session_state["latest_pr"])
            st.markdown("### βœ… Approval Email (send this via Outlook/Gmail/n8n):")
            st.markdown(approval_email)
            st.session_state["approval_email"] = approval_email

    if "latest_pr" in st.session_state:
        if st.button("3️⃣ Simulate Approval β†’ Generate PO"):
            po_md = create_po_from_pr(st.session_state["latest_pr"], buyer_org, buyer_address_q, supplier_email_q)
            st.markdown("### βœ… Generated PO (from approved PR)")
            st.markdown(po_md)
            st.session_state["po_md"] = po_md

    if "po_md" in st.session_state:
        if st.button("4️⃣ Prepare Supplier Email"):
            supplier_mail = create_supplier_email(st.session_state["po_md"], supplier_email_q)
            st.markdown("### βœ… Supplier Email (copy & send)")
            st.markdown(supplier_mail)
            st.info("To auto-send this, connect SMTP or n8n webhook.")