Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| from datetime import datetime | |
| import os | |
| import configparser # For activating the config | |
| from PIL import Image, ImageFilter | |
| import io | |
| import base64 | |
| from google.cloud import bigquery | |
| from google.oauth2 import service_account | |
| import logging | |
| from threading import Thread | |
| from pyngrok import conf, ngrok | |
| import requests | |
| # Manually set ngrok path | |
| # ngrok_path = "/Users/ninadmandavkar/Desktop/ngrok/ngrok 3" | |
| # Set the ngrok path in the configuration | |
| # config = conf.get_default() | |
| # config.ngrok_path = ngrok_path | |
| # Set your ngrok auth token | |
| # ngrok.set_auth_token('2jQ6LRMBFqe25TP7o2ugti9EH6Y_3mBzBYbsjZmhh69eGq2Q1') | |
| # logging.basicConfig(level=logging.INFO) | |
| ## Single value - 268 --> 675 | |
| ## Feature Specific - 676 --> 980 | |
| global_user_data = [] # For appending user_data | |
| global_data_rows = [] # For appending data rows | |
| # Function to initialize session state | |
| def initialize_session_state(): | |
| if 'data' not in st.session_state: | |
| st.session_state.data = [] | |
| if 'alphabet_counter' not in st.session_state: | |
| st.session_state.alphabet_counter = 0 | |
| if 'serial_counter' not in st.session_state: | |
| st.session_state.serial_counter = -1 | |
| # Initialize global_data_rows if not already initialized | |
| if 'global_data_rows' not in st.session_state: | |
| st.session_state.global_data_rows = [] | |
| # Function to save user data | |
| def save_user_data(user_data): | |
| st.session_state.data.append(user_data) | |
| # Function to save Slab data | |
| def save_slab_data(new_row): | |
| st.session_state.data.append(new_row) | |
| # Function to generate PM_id | |
| def generate_rule_id(user_data): | |
| company_id = user_data.get('Company ID', '') | |
| ordering_channels = user_data.get('Product lines', '') | |
| fulfilling_location = user_data.get('Fulfilling Location', '') | |
| application_id = user_data.get('Application ID', '') | |
| selected_fee_type = user_data.get('Fee Type', '') | |
| selected_variable_type = user_data.get('Variable Type', '') | |
| selected_chargeable_on = user_data.get('Chargeable on', '') | |
| selected_fee_nature = user_data.get('Fee Nature', '') | |
| threshold = user_data.get('Threshold option', '') | |
| # Ensure all fields are strings and handle None or empty values | |
| company_id = str(company_id).zfill(5)[:5] if company_id else '00000' | |
| ordering_channels = str(ordering_channels)[:2] if ordering_channels else '00' | |
| fulfilling_location = str(fulfilling_location)[:2] if fulfilling_location else '00' | |
| application_id = str(application_id)[:2] if application_id else '00' | |
| selected_fee_type = str(selected_fee_type)[:2] if selected_fee_type else '00' | |
| selected_variable_type = str(selected_variable_type)[:2] if selected_variable_type else '00' | |
| selected_chargeable_on = str(selected_chargeable_on)[:2] if selected_chargeable_on else '00' | |
| selected_fee_nature = str(selected_fee_nature)[:2] if selected_fee_nature else '00' | |
| threshold = str(threshold)[:2] if threshold else '00' | |
| # Extract first 2 characters from each field and ensure proper length | |
| rule_id_parts = [ | |
| company_id, # Ensure 5 characters | |
| ordering_channels, # Ensure 2 characters | |
| fulfilling_location, # Ensure 2 characters | |
| application_id, # Ensure 2 characters | |
| selected_fee_type, # Ensure 2 characters | |
| selected_variable_type, # Ensure 2 characters | |
| selected_chargeable_on, # Ensure 2 characters | |
| selected_fee_nature, # Ensure 2 characters | |
| threshold # Ensure 2 characters | |
| ] | |
| rule_id = '_'.join(rule_id_parts) # Join parts with an underscore | |
| return rule_id | |
| # Function to generate Plan ID | |
| def generate_plan_id(user_data): | |
| initialize_session_state() # Ensure session state is initialized | |
| alphabet_counter = st.session_state.alphabet_counter | |
| serial_counter = st.session_state.serial_counter | |
| company_id = user_data.get('Company ID', '') # Get company_id from user_data | |
| if company_id is None or not company_id.strip(): | |
| company_id = '' | |
| # Increment serial counter and reset if it reaches 999999 | |
| serial_counter += 1 | |
| if serial_counter > 999999: | |
| serial_counter = 0 | |
| alphabet_counter += 1 | |
| # Save updated counters back to session state | |
| st.session_state['alphabet_counter'] = alphabet_counter | |
| st.session_state['serial_counter'] = serial_counter | |
| # Calculate alphabet ('a' to 'z') | |
| current_alphabet = chr(alphabet_counter % 26 + ord('a')) | |
| # Format serial counter as six-digit number | |
| serial_number = str(serial_counter).zfill(6) | |
| # Get the first 5 characters of company_id and pad it with zeros | |
| company_id_part = company_id[:5].zfill(5) | |
| # Generate the plan_id | |
| plan_id = f"{company_id_part}_{current_alphabet}_{serial_number}" | |
| return plan_id | |
| # Function to display saved records as a table and save to CSV | |
| def display_saved_records(): | |
| html_content_5 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 25px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Saved records</h1> | |
| """ | |
| st.markdown(html_content_5, unsafe_allow_html=True) | |
| df = pd.DataFrame(st.session_state.data) | |
| if not df.empty: | |
| # Apply generate_rule_id function to each row to generate rule_id | |
| df['rule_id'] = df.apply(lambda row: generate_rule_id(row), axis=1) | |
| # Display DataFrame with increased height | |
| st.write(df.style.set_table_attributes('style="font-size: 14px; line-height: 18px; width: auto; height: auto;"')) | |
| # Save records to CSV | |
| folder_path = "data" # Folder name | |
| os.makedirs(folder_path, exist_ok=True) # Create folder if it doesn't exist | |
| file_path = os.path.join(folder_path, "records.csv") | |
| # Save DataFrame to CSV without index | |
| df.to_csv(file_path, index=False) | |
| # Custom CSS styles | |
| button_styles = """ | |
| <style> | |
| .stDownloadButton button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 20px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| text-decoration: none; | |
| text-align: center; | |
| transition: background-color 0.3s ease; | |
| } | |
| .stDownloadButton button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render custom CSS styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| # Define file path (replace with your actual file path) | |
| folder_path = "data" | |
| file_path = os.path.join(folder_path, "records.csv") | |
| # Function to read file data | |
| def read_file(file_path): | |
| with open(file_path, 'rb') as f: | |
| file_data = f.read() | |
| return file_data | |
| # Download button with custom styling | |
| st.download_button( | |
| label="Download CSV", | |
| data=read_file(file_path), | |
| file_name="records.csv", | |
| mime="text/csv", | |
| ) | |
| # Function to load theme configuration | |
| def load_theme_config(): | |
| config = configparser.ConfigParser() | |
| config.read('config.toml') | |
| # Extract theme settings | |
| theme_settings = config['theme'] | |
| return theme_settings | |
| # Initialize session state | |
| initialize_session_state() | |
| theme_settings = load_theme_config() | |
| # Apply theme settings to Streamlit | |
| st.set_page_config( | |
| page_title="Plan maker", | |
| page_icon="Fynd copy.png", # Specify your own page icon | |
| layout="centered", # "wide" or "centered" | |
| initial_sidebar_state="auto", # "auto", "expanded", "collapsed" | |
| ) | |
| # Display the image in the sidebar | |
| # st.sidebar.image('Fynd_logo2.png', width=300) | |
| st.sidebar.markdown(""" | |
| <style> | |
| .left-aligned-image { | |
| display: flex; | |
| justify-content: flex-start; | |
| width: 100%; | |
| } | |
| .left-aligned-image img { | |
| width: 100%; | |
| margin-bottom: 20px; | |
| height: auto; | |
| border-radius: 15px; | |
| } | |
| </style> | |
| <div class="left-aligned-image"> | |
| <img src="https://www.medianews4u.com/wp-content/uploads/2021/02/Fynd-Platform-encourages-SMEs-to-start-an-online-business-with-a-new-campaign.jpg" alt="Fynd Image"> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| html_content = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 50px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Plan maker</h1> | |
| """ | |
| st.markdown(html_content, unsafe_allow_html=True) | |
| st.write(" ") | |
| user_name = st.sidebar.text_input("Enter your name:") | |
| html_content_1 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 22px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Section 1: Plan Info</h1> | |
| """ | |
| st.sidebar.markdown(html_content_1, unsafe_allow_html=True) | |
| if 'company_name' not in st.session_state: | |
| st.session_state['company_name'] = "Company name not available" | |
| v1 = ["Commerce India", "Reliance", "Commerce Global", "Government Projects", "Individual BH"] | |
| business_head = st.sidebar.selectbox("Business Head", [""] + v1, help="Business Head is used for cost centre allocation") | |
| # Initialize company_name in session state | |
| if 'company_name' not in st.session_state: | |
| st.session_state['company_name'] = "" | |
| # User inputs Company ID | |
| company_id = st.sidebar.text_input("Company ID", help="Enter the company ID") | |
| company_id_int = None | |
| if company_id.strip(): | |
| try: | |
| company_id_int = int(company_id.strip()) | |
| st.session_state['company_id'] = company_id.strip() #ALways store the company id in session state | |
| except ValueError: | |
| st.error("Invalid Company ID. Please enter a valid integer.") | |
| company_id_int = None | |
| # Construct the API URL and fetch data only if company_id_int is valid | |
| if company_id_int is not None: | |
| try: | |
| api_url = f"https://api.boltic.io/service/platform/bolt/share/v1/data?api_token=eyJpZCI6IjU4OTdmZjZlLTMwMTYtNDZjMC1hMzdlLTJmNjBkMjhjYjc5YyIsInRlbmFudCI6ImdvZnluZGNvbSJ9&batch_size=10000&display_meta=true&cmpid={company_id_int}" | |
| response = requests.get(api_url) | |
| if response.status_code == 200: | |
| data = response.json() | |
| if "results" in data and len(data["results"]) > 0: | |
| st.session_state['company_name'] = data["results"][0].get("company_name", "Company name not found") | |
| else: | |
| st.session_state['company_name'] = "Company name not found" | |
| else: | |
| st.session_state['company_name'] = f"Error: Unable to fetch data (Status code: {response.status_code})" | |
| except Exception as e: | |
| st.session_state['company_name'] = f"An error occurred: {e}" | |
| else: | |
| st.session_state['company_name'] = "" # Set to an empty string if Company ID is not provided or invalid | |
| # Display the company name | |
| st.sidebar.text_input("Company Name", value=st.session_state['company_name'], disabled=False) | |
| currency = st.sidebar.radio("Currency", options= ["INR", "USD"], help= "Select the type of currency", index =None) | |
| bundle_by = st.sidebar.radio(options=["Single value", "Feature specific"], label="Bundle by", help = "Select the bundle", index=None) | |
| ################################################## Feature Specific ########################################################## | |
| if bundle_by == "Feature specific": | |
| plan_name = st.sidebar.text_input("Plan Name", help="Enter the name of the plan") | |
| plan_description = st.sidebar.text_area("Plan Description", max_chars=250, help="Describe the plan") | |
| plan_start_date = st.sidebar.date_input("Plan Start Date", value=datetime.now(), help="Select the start date of the plan") | |
| # Section 3: Defining products for each dropdown | |
| product_options = ["GoFynd", "Uniket", "ONDC", "StoreOS", "Website", "OMS", "WMS", "TMS", "GMC", "Partner", | |
| "Catalog Cloud", "FCP", "PixelBin", "Boltic", | |
| "CoPilot"] | |
| fee_type_options = ["Development", "Licensing", "Logistics", "Marketing", "Packaging", "Subscription", "Transaction"] | |
| fee_nature_options = ["Fixed %", "Flat currency", "Slab based", "As per rate card"] | |
| variable_options = ["Application", "Bag", "Extension", "Integration", "Order", "Platform", "Resource", "Shipment", "User", "B2B", "B2C"] | |
| chargeable_on_options = ["Active", "Build", "Cancelled", "Delivered", "DTO", "Invoiced", "Packed", "Picked", "Placed", "Return Window", "RTO", "Setup", "SiteOps-hr", "Subscribed", "TechOps-hr"] | |
| plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"] | |
| payment_method_options = ["Prepaid", "Postpaid"] | |
| # Initialize session state variables if they don't exist | |
| if 'new_mapping' not in st.session_state: | |
| st.session_state['new_mapping'] = {} | |
| if 'file_data' not in st.session_state: | |
| st.session_state['file_data'] = None | |
| if 'mapping_mode' not in st.session_state: | |
| st.session_state['mapping_mode'] = None # None, 'default', 'custom' | |
| if 'button_clicked' not in st.session_state: | |
| st.session_state['button_clicked'] = None | |
| # Function to handle custom button click | |
| def custom_button_click(): | |
| st.session_state.button_clicked = 'custom' | |
| # Function to handle default button click | |
| def default_button_click(): | |
| st.session_state.button_clicked = 'default' | |
| # Display buttons without immediate execution on click | |
| col1, col2 = st.sidebar.columns([0.25, 0.45]) | |
| with col1: | |
| default_clicked = st.button("Default mapping") | |
| with col2: | |
| custom_clicked = st.button("Custom mapping") | |
| # Determine action based on button clicked | |
| if default_clicked: | |
| default_button_click() | |
| elif custom_clicked: | |
| custom_button_click() | |
| # Define CSS styles for the button | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| # Handle Default Mapping | |
| if st.session_state.button_clicked == 'default': | |
| # Default mapping data | |
| new_mapping = { | |
| "GoFynd": { | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "Uniket": { | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "ONDC": { | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "StoreOS": { | |
| "Licensing": { | |
| "Application": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Application": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "Website": { | |
| "Licensing": { | |
| "Application": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Application": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| }, | |
| "Development": { | |
| "Application": ["Build"] | |
| } | |
| }, | |
| "OMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| } | |
| }, | |
| "WMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"], | |
| "B2B": ["Invoiced"], | |
| "B2C": ["Invoiced"] | |
| } | |
| }, | |
| "TMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| } | |
| }, | |
| "GMC": { | |
| "Development": { | |
| "Extension": ["Build"], | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Partner": { | |
| "Development": { | |
| "Extension": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Catalog Cloud": { | |
| "Development": { | |
| "Extension": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "FCP": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "PixelBin": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Boltic": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "CoPilot": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| } | |
| } | |
| st.session_state['new_mapping'] = new_mapping | |
| st.session_state['mapping_mode'] = 'default' | |
| html_content_1 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 22px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Section 2: Rule Info</h1> | |
| """ | |
| st.sidebar.markdown(html_content_1, unsafe_allow_html=True) | |
| # Handle Custom Mapping | |
| elif st.session_state.button_clicked == 'custom': | |
| # Define CSS styles for the button | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| # File upload | |
| uploaded_file = st.sidebar.file_uploader("Upload a file:", type=['csv', 'xlsx'], key='file_uploader') | |
| html_content_1 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 22px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Section 2: Rule Info</h1> | |
| """ | |
| st.sidebar.markdown(html_content_1, unsafe_allow_html=True) | |
| if uploaded_file is not None: | |
| try: | |
| # Read the file, treating the first row as the header | |
| if uploaded_file.name.endswith('.csv'): | |
| data = pd.read_csv(uploaded_file, header=0) | |
| elif uploaded_file.name.endswith('.xlsx'): | |
| data = pd.read_excel(uploaded_file, header=0) | |
| if st.sidebar.button("Overwrite headers"): | |
| # Rename the headers | |
| new_headers = ['ordering_channel', 'fee_type', 'variable_type', 'chargeable_on'] | |
| data.columns = new_headers | |
| # Save the data to session state | |
| st.session_state['file_data'] = data | |
| # Initialize the mapping | |
| new_mapping = {} | |
| # Build the mapping | |
| for _, row in data.iterrows(): | |
| ordering_channel = row['ordering_channel'] | |
| fee_type = row['fee_type'] | |
| variable_type = row['variable_type'] | |
| chargeable_on = row['chargeable_on'] | |
| if ordering_channel not in new_mapping: | |
| new_mapping[ordering_channel] = {} | |
| if fee_type not in new_mapping[ordering_channel]: | |
| new_mapping[ordering_channel][fee_type] = {} | |
| if variable_type not in new_mapping[ordering_channel][fee_type]: | |
| new_mapping[ordering_channel][fee_type][variable_type] = [] | |
| if chargeable_on not in new_mapping[ordering_channel][fee_type][variable_type]: | |
| new_mapping[ordering_channel][fee_type][variable_type].append(chargeable_on) | |
| st.session_state['new_mapping'] = new_mapping | |
| st.session_state['mapping_mode'] = 'custom' | |
| except Exception as e: | |
| st.error(f"Error reading the file: {e}") | |
| # Handle mapping display | |
| # Initialize session state variables if they don't exist | |
| # Initialize session state variables with default values if not already set | |
| if 'business_head' not in st.session_state: | |
| st.session_state['business_head'] = None | |
| if 'company_id' not in st.session_state: | |
| st.session_state['company_id'] = None | |
| if 'company_name' not in st.session_state: | |
| st.session_state['company_name'] = None | |
| if 'currency' not in st.session_state: | |
| st.session_state['currency'] = None | |
| if 'bundle_by' not in st.session_state: | |
| st.session_state['bundle_by'] = None | |
| if 'plan_name' not in st.session_state: | |
| st.session_state['plan_name'] = None | |
| if 'plan_description' not in st.session_state: | |
| st.session_state['plan_description'] = None | |
| if 'selected_ordering_channel' not in st.session_state: | |
| st.session_state['selected_ordering_channel'] = None | |
| if 'fulfilling_location' not in st.session_state: | |
| st.session_state['fulfilling_location'] = None | |
| if 'application_id' not in st.session_state: | |
| st.session_state['application_id'] = None | |
| if 'selected_fee_type' not in st.session_state: | |
| st.session_state['selected_fee_type'] = None | |
| if 'selected_variable_type' not in st.session_state: | |
| st.session_state['selected_variable_type'] = None | |
| if 'selected_chargeable_on' not in st.session_state: | |
| st.session_state['selected_chargeable_on'] = None | |
| if 'selected_fee_nature' not in st.session_state: | |
| st.session_state['selected_fee_nature'] = None | |
| if 'user_input_3' not in st.session_state: | |
| st.session_state['user_input_3'] = None | |
| if 'usage_3' not in st.session_state: | |
| st.session_state['usage_3'] = None | |
| if 'Capping_or_Minimum_Guarantee_3' not in st.session_state: | |
| st.session_state['Capping_or_Minimum_Guarantee_3'] = None | |
| if 'threshold' not in st.session_state: | |
| st.session_state['threshold'] = None | |
| if 'expected_billing' not in st.session_state: | |
| st.session_state['expected_billing'] = None | |
| if 'selected_payment_method' not in st.session_state: | |
| st.session_state['selected_payment_method'] = None | |
| if 'selected_plan_validity' not in st.session_state: | |
| st.session_state['selected_plan_validity'] = None | |
| if 'final_billing' not in st.session_state: | |
| st.session_state['final_billing'] = None | |
| if 'fee_reversal' not in st.session_state: | |
| st.session_state['fee_reversal'] = None | |
| if 'reversal_per' not in st.session_state: | |
| st.session_state['reversal_per'] = None | |
| # Check if 'mapping_mode' exists in session state before using it | |
| if 'mapping_mode' in st.session_state and st.session_state['mapping_mode']: | |
| # 1st layer: Select ordering channel | |
| selected_ordering_channel = st.sidebar.selectbox( | |
| "Product lines", | |
| [""] + list(st.session_state['new_mapping'].keys()), | |
| help="Select a Product line", | |
| key='ordering_channel' | |
| ) | |
| if selected_ordering_channel: | |
| selected_ordering_channel = str(selected_ordering_channel) or int(selected_ordering_channel) | |
| # Determine fulfilling_location and application_id based on selected_ordering_channel | |
| if any(channel in selected_ordering_channel for channel in ["TMS", "GMC", "Catalog Cloud"]): | |
| st.session_state['fulfilling_location'] = None | |
| st.session_state['application_id'] = None | |
| else: | |
| abc = ["Store", "Warehouse"] | |
| st.session_state['fulfilling_location'] = st.sidebar.selectbox( | |
| "Fulfilling Location", [""] + abc, help="Select the fulfilling location" | |
| ) | |
| st.session_state['application_id'] = st.sidebar.text_input( | |
| "Application ID", key="application_id_input", help="Enter the application ID" | |
| ) | |
| # Use the session state variables in your app | |
| fulfilling_location = st.session_state['fulfilling_location'] | |
| application_id = st.session_state['application_id'] | |
| # 2nd layer: Select fee type based on the selected ordering channel | |
| if 'selected_fee_type' not in st.session_state: | |
| st.session_state['selected_fee_type'] = None | |
| fee_types_for_channel = st.session_state['new_mapping'].get(selected_ordering_channel, {}).keys() | |
| fee_types_for_channel = list(fee_types_for_channel) | |
| if fee_types_for_channel: | |
| # Define selected_fee_type based on user input | |
| st.session_state['selected_fee_type'] = st.selectbox( | |
| "Fee Type", | |
| [""] + fee_types_for_channel, | |
| help="Fee type is a revenue head for grouping the revenue", | |
| key='fee_type' | |
| ) | |
| # Access selected_fee_type for any session state operations | |
| selected_fee_type = st.session_state['selected_fee_type'] | |
| # 3rd layer: Select variable type based on the selected fee type | |
| variable_type_options = [] | |
| if selected_fee_type: | |
| details = st.session_state['new_mapping'].get(selected_ordering_channel, {}) | |
| variables = details.get(selected_fee_type, {}) | |
| variable_type_options = list(variables.keys()) | |
| st.session_state['selected_variable_type'] = st.selectbox( | |
| "Variable Type", | |
| [""] + variable_type_options, | |
| help="Variable type is an attribute on which revenue calculation will be done", | |
| key='variable_type' | |
| ) | |
| selected_variable_type = st.session_state['selected_variable_type'] | |
| # 4th layer: Select chargeable on based on the selected variable type | |
| chargeable_on_options = [] | |
| if selected_variable_type: | |
| chargeable_on_options = variables.get(selected_variable_type, []) | |
| st.session_state['selected_chargeable_on'] = st.selectbox( | |
| "Chargeable on", | |
| [""] + chargeable_on_options, | |
| help="Chargeable on is a service status on which the above fee will be applicable", | |
| key='chargeable_on' | |
| ) | |
| selected_chargeable_on = st.session_state['selected_chargeable_on'] | |
| else: | |
| st.write("No fee types available for the selected ordering channel.") | |
| else: | |
| st.write("") | |
| # Create an empty DataFrame with the desired column names | |
| slabs_df = pd.DataFrame(columns=["Slab", "Max_value", "Commercial_value", "Usage", "Capping/Min_Guarantee_value", "Threshold"]) | |
| ttt = ["Fixed %", "Flat currency", "Slab based"] | |
| selected_fee_nature = st.selectbox("Fee Nature:", [""] + ttt, key="fee_nature_select", help = "Fee nature is an option to consume the price in flat / % / slab") | |
| if selected_fee_nature == "Slab based": | |
| def add_data(slab, max_value, user_input, Usage, Capping_or_Minimum_Guarantee, threshold): | |
| # Convert values to int if not None | |
| max_value = int(max_value.strip()) if max_value else None | |
| user_input_11 = int(user_input.strip()) if user_input else None | |
| try: | |
| user_input_22 = float(user_input_11) | |
| user_input = "{:.2f}".format(user_input_22) | |
| except (TypeError, ValueError): | |
| user_input = 0 | |
| Usage = int(Usage.strip()) if Usage else None | |
| Capping_or_Minimum_Guarantee = int(Capping_or_Minimum_Guarantee.strip()) if Capping_or_Minimum_Guarantee else None | |
| # Create a new row dictionary | |
| new_row = { | |
| "Slab": slab, | |
| "Max_value": max_value, | |
| "Commercial_value": user_input, | |
| "Usage": Usage, | |
| "Capping/Min_Guarantee_value": Capping_or_Minimum_Guarantee, | |
| "Threshold": threshold | |
| } | |
| # Append new_row to global list of rows in session state | |
| st.session_state.global_data_rows.append(new_row) | |
| def main(): | |
| # Initialize session state if not already initialized | |
| if 'global_data_rows' not in st.session_state: | |
| st.session_state.global_data_rows = [] | |
| # Inputs for adding data | |
| col1, col2 = st.columns([2, 2]) | |
| with col1: | |
| slab = st.selectbox("Slab:", [1, 2, 3], key="slab_select") # Selectbox for slab numbers | |
| user_input = st.text_input("Commercial Value:", key="user_input") | |
| Capping_or_Minimum_Guarantee = st.text_input("Capping/Min_Guarantee:", key="Capping_or_Minimum_Guarantee_input") | |
| with col2: | |
| max_value = st.text_input("Max value:", key="max_value_input") | |
| Usage = st.text_input("Usage:", key="Usage_input") | |
| threshold = st.text_input("Threshold:", key="threshold_input") | |
| # Button to add data | |
| if st.button("Add Data", key="add_data_button"): | |
| if not (slab and user_input and Capping_or_Minimum_Guarantee): | |
| st.warning("Please fill in all required fields.") | |
| else: | |
| add_data(slab, max_value, user_input, Usage, Capping_or_Minimum_Guarantee, threshold) | |
| st.success(f"Data for Slab '{slab}' added successfully!") | |
| # Display all entries in a single table | |
| if global_data_rows: | |
| st.subheader("All Slabs Data Summary") | |
| for i, row in enumerate(global_data_rows): | |
| st.write(f"Entry {i + 1}:") | |
| st.table([row]) | |
| if __name__ == "__main__": | |
| main() | |
| user_input_3 = 0 | |
| elif selected_fee_nature in ["Fixed %", "Flat currency"]: | |
| user_input_1 = st.number_input("Enter Commercial value:",min_value=0.0, help = "Enter the Commercial value") | |
| try: | |
| user_input_2 = float(user_input_1) | |
| user_input_3 = "{:.2f}".format(user_input_2) | |
| except (TypeError, ValueError): | |
| user_input_3 = 0 | |
| # 6th layer: Expected Billing | |
| selected_fee_type = st.session_state['selected_fee_type'] | |
| selected_variable_type = st.session_state['selected_variable_type'] | |
| fee_reversal_options = ["RTO", "DTO", "Cancel"] | |
| fee_reversal = st.multiselect("Fee Reversal", fee_reversal_options, help = "Fee reversal is an option of reversing to be given to any fee on a particular service status") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None | |
| reversal_per = st.number_input("Reversal %", min_value= 0.0, help = "Enter the reversal percentage") if selected_fee_type == "Transaction" and selected_variable_type == "Bag" else None | |
| usage_1 = st.number_input(f"Usage limit for {selected_variable_type}", min_value=0.0, help="Enter the usage limit") | |
| usage_2 = float(usage_1) | |
| usage_3 = "{:.2f}".format(usage_2) | |
| Product_1 = usage_1 * user_input_1 if selected_fee_nature in ["Fixed %", "Flat currency"] else 0 | |
| Product_2 = float(Product_1) | |
| Product_3 = "{:.2f}".format(Product_2) | |
| abc = ['Capping value', 'Minimum Guarantee'] | |
| threshold = st.selectbox("Threshold option:", [""] + abc, help = "If Minimum guarantee is set as threshold option then Expected billing will be the higher value b/w 'Commercial*Usage' & 'Threshold' and if it is set to Capping then Expected billing will be the lower value b/w 'Commercial*Usage' & 'Threshold'") | |
| Capping_or_Minimum_Guarantee_1 = st.number_input(f"Threshold value for {selected_variable_type}", min_value=0.0, | |
| help="Enter the Capping/Minimum Gauarntee value") | |
| Capping_or_Minimum_Guarantee_2 = float(Capping_or_Minimum_Guarantee_1) | |
| Capping_or_Minimum_Guarantee_3 = "{:.2f}".format(Capping_or_Minimum_Guarantee_2) | |
| initial_expected_billing = Product_1 | |
| expected_billing = None | |
| if threshold == 'Capping value': | |
| expected_billing = min(Product_1, Capping_or_Minimum_Guarantee_1) | |
| elif threshold == 'Minimum Guarantee': | |
| expected_billing = max(Product_1, Capping_or_Minimum_Guarantee_1) | |
| else: | |
| expected_billing = initial_expected_billing # Default to initial Product value if no threshold selected | |
| plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"] | |
| selected_plan_validity = st.selectbox("Plan Validity", [""] + plan_validity_options, help="Plan validity defines the periodicity of calculation for the above billing", key="plan_vd_2") | |
| html_content_7 = f""" | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 20px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Expected Monthly Billing (excluding GST): {expected_billing}</h1> | |
| """ | |
| # Using Streamlit to display the HTML content | |
| st.markdown(html_content_7, unsafe_allow_html=True) | |
| initial_net_billing = 0 | |
| final_billing = 0 | |
| if selected_plan_validity == 'One time' or selected_plan_validity == 'Monthly': | |
| final_billing = 1*expected_billing | |
| elif selected_plan_validity == 'Quarterly': | |
| final_billing = 3*expected_billing | |
| elif selected_plan_validity == 'Bi-Annually': | |
| final_billing = 6*expected_billing | |
| elif selected_plan_validity == 'Annually': | |
| final_billing = 12*expected_billing | |
| else: | |
| final_billing = initial_net_billing | |
| html_content_8 = f""" | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 20px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Net total billing (excluding GST): {final_billing}</h1> | |
| """ | |
| # Using Streamlit to display the HTML content | |
| st.markdown(html_content_8, unsafe_allow_html=True) | |
| payment_method_options = ["Prepaid", "Postpaid"] | |
| selected_payment_method = st.selectbox("Payment Method", [""] + payment_method_options, help="Payment method defines the mode of payment of the plan", key="py_vd_2") | |
| # Submit button | |
| # Define CSS styles for the button | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| rule_id = None | |
| plan_id = None | |
| # business_head = st.session_state['business_head'] | |
| company_name = st.session_state['company_name'] | |
| company_id = st.session_state['company_id'] | |
| # currency = st.session_state['currency'] | |
| # # bundle_by = st.session_state['bundle_by'] | |
| # plan_name = st.session_state['plan_name'] | |
| # plan_description = st.session_state['plan_description'] | |
| # selected_ordering_channel = st.session_state['selected_ordering_channel'] | |
| # fulfilling_location = st.session_state['fulfilling_location'] | |
| # application_id = st.session_state['application_id'] | |
| # selected_fee_type = st.session_state['selected_fee_type'] | |
| # selected_variable_type = st.session_state['selected_variable_type'] | |
| # selected_chargeable_on = st.session_state['selected_chargeable_on'] | |
| # user_input_3 = st.session_state['user_input_3'] | |
| # usage_3 = st.session_state['usage_3'] | |
| # Capping_or_Minimum_Guarantee_3 = st.session_state['Capping_or_Minimum_Guarantee_3'] | |
| # fee_reversal = st.session_state['fee_reversal'] | |
| # reversal_per = st.session_state['reversal_per'] | |
| # threshold = st.session_state['threshold'] | |
| # expected_billing = st.session_state['expected_billing'] | |
| # selected_payment_method = st.session_state['selected_payment_method'] | |
| # selected_plan_validity = st.session_state['selected_plan_validity'] | |
| # final_billing = int(st.session_state['final_billing']) if st.session_state['final_billing'] is not None else 0 | |
| if st.button("Submit", key ='submit_button'): | |
| # Save user data | |
| user_data = { | |
| "Business_Head": business_head, | |
| "Company_ID": company_id.strip() if company_id else None, | |
| "Company_Name": company_name, | |
| "Currency": currency, | |
| "Bundle_by": bundle_by, | |
| "Plan_Name": plan_name, | |
| "Plan_Description": plan_description, | |
| "Product_lines": selected_ordering_channel, | |
| "Fulfilling_Location": fulfilling_location, | |
| "Application_ID": application_id, | |
| "Fee_Type": selected_fee_type, | |
| "Variable_Type": selected_variable_type, | |
| "Chargeable_on": selected_chargeable_on, | |
| "Fee_Nature": selected_fee_nature, | |
| "Commercial_value": user_input_3, | |
| "Fee_reversal": 0, | |
| "Reversal_%": 0, | |
| "Usage_limit": usage_3, | |
| "Threshold_value": Capping_or_Minimum_Guarantee_3, | |
| "Threshold_option": threshold, | |
| "Expected_Billing": expected_billing, | |
| "Payment_Method": selected_payment_method, | |
| "Plan_Validity": selected_plan_validity, | |
| "Net_total_billing":int(final_billing) | |
| } | |
| # Generate rule_id and plan_id | |
| rule_id = generate_rule_id(user_data) | |
| plan_id = generate_plan_id(user_data) | |
| # Update user_data with generated IDs | |
| user_data['rule_id'] = rule_id | |
| user_data['plan_id'] = plan_id | |
| # Save the user data locally and to session state | |
| # global_user_data.append((user_name, user_data)) | |
| save_user_data(user_data) | |
| # Display saved records | |
| display_saved_records() | |
| # Store created_at, rule_id, and plan_id in session state | |
| st.session_state['created_at'] = datetime.now().isoformat() | |
| st.session_state['rule_id'] = rule_id | |
| st.session_state['plan_id'] = plan_id | |
| if st.button("Export data to BQ"): | |
| def insert_into_bq(user_data, project_id, dataset_id, table_id, service_account_info): | |
| try: | |
| # Use from_service_account_info instead of from_service_account_file | |
| credentials = service_account.Credentials.from_service_account_info(service_account_info) | |
| # Initialize a BigQuery client | |
| client = bigquery.Client(credentials=credentials, project=project_id) | |
| logging.info("BigQuery client initialized successfully.") | |
| # Specify the table reference | |
| table_ref = f"{project_id}.{dataset_id}.{table_id}" | |
| table = client.get_table(table_ref) | |
| logging.info(f"Table reference obtained: {table_ref}") | |
| # Insert form data into the table | |
| rows_to_insert = [user_data] | |
| errors = client.insert_rows_json(table, rows_to_insert) | |
| if errors: | |
| logging.error(f"Errors occurred while inserting rows: {errors}") | |
| st.error(f"Errors occurred while inserting rows: {errors}") | |
| else: | |
| logging.info("Insert successful") | |
| st.success("Insert successful") | |
| except Exception as e: | |
| logging.exception("An error occurred during the BigQuery insert operation.") | |
| st.error(f"An error occurred: {e}") | |
| project_id = "fynd-db" | |
| dataset_id = "finance_dwh" | |
| table_id = "plan_v2" | |
| fulfilling_location = st.session_state['fulfilling_location'] | |
| application_id = st.session_state['application_id'] | |
| # bundle_by = st.session_state['bundle_by'] | |
| # Retrieve created_at, rule_id, and plan_id from session state | |
| created_at = st.session_state.get('created_at') | |
| rule_id = st.session_state.get('rule_id') | |
| plan_id = st.session_state.get('plan_id') | |
| user_data = { | |
| "Business_Head": business_head, | |
| "Company_ID": company_id, | |
| "Company_Name": company_name, | |
| "Currency": currency, | |
| "Bundle_by": bundle_by, | |
| "Plan_Name": plan_name, | |
| "Plan_Description": plan_description, | |
| "Product_lines": selected_ordering_channel, | |
| "Fulfilling_Location": fulfilling_location, | |
| "Application_ID": application_id, | |
| "Fee_Type": selected_fee_type, | |
| "Variable_Type": selected_variable_type, | |
| "Chargeable_on": selected_chargeable_on, | |
| "Fee_Nature": selected_fee_nature, | |
| "Commercial_value": user_input_3, | |
| "Fee_reversal": 0, | |
| "Reversal_%": 0, | |
| "Usage_limit": usage_3, | |
| "Threshold_value": Capping_or_Minimum_Guarantee_3, | |
| "Threshold_option": threshold, | |
| "Expected_Billing": expected_billing, | |
| "Payment_Method": selected_payment_method, | |
| "Plan_Validity": selected_plan_validity, | |
| "rule_id": rule_id, | |
| "plan_id": plan_id, | |
| "created_at": created_at, | |
| "Net_total_billing":int(final_billing) | |
| } | |
| save_user_data(user_data) # Save user data after submission | |
| service_account_info = { | |
| "type": "service_account", | |
| "project_id": "fynd-db", | |
| "private_key_id": "48954327ef172acc3091a91881840dc353ff0413", | |
| "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmIs0vgXflZmHD\n0IeHCiDEXavRb2GvRQqkCZGLy/EHFO7XLmpNrFzZHTSQach6HErARWTMsd2AMIA5\nHbmjEyt9deTOMUmICszkwNwpn6pzuoF2v4+fL2PQ4VBElLfCv4qbP9JGljvLsj5b\nC9UWe9rWgRrw2Z88LlVmFy3k4Om80Q57gW3hSYZpG4rBhC9+YRXjZ+Iq5SFEJQ+U\nj8ej7q6DnI8Prbvw/e13JH1pxm9AUQDm+sTsBmvjh4Ye02vKbfUP+pFOM0eC3Eoa\nOyG7unZnDuAaK9g87xVjd9HtD6MfaM0EHAEF1eyC4UqeiXTbVMwi7+0IGA2evEDZ\n3WRR2i+lAgMBAAECggEAF7Vis7NVsVqFfCS/moFTAMLfWLF87r67EIK/DwSpHloZ\n5YJdsDz3ORKmZC98aRSthDfC9UUyt270dXItAj0jmTFgWB6HgE8OQ1zUbmo3MHG+\ntPwMWmqwY2gsBMV2Xefot1QJxYH+AYkrxeFv5NgC+FaPSiy8QSHZlQqcxYtlP8kY\nzv8QFMgZ3b0sixK+YcSjCRXHu/DznnS/ZU7XlTALxANa50hT11rVLq6zYDF40fqC\nOWCOZvupjMOnNimXCWn7q6D1F8S/IMYlnHArJpEb7SdbJnJzxUvJC2rrMSoY896r\nyFEVhlElWp5GfTopu0WnL7iaw3pukM1OtpanFAk29wKBgQDW+yMzL7RiQ5LdElVP\n7Ml5hs+t6cjrUJTgBI8Uf9qGxE+tMe7Ye1fyJfbYslbOYO9xIUUT1jJmU6jadNWX\nA7UT59/IjvAOBIYyMEdh6Xo+H6ggW8DeU1HSdvixnQdgi0c03E6OCbOKi9E/UzK/\nTK2RBJJLN4MCiNL0FzrhTuxyEwKBgQDF1cz9Sb2UbrL5hr8LdcEH0ctatNlhJcSN\nnMd0Fn+e1EAkip+Hs9HmTvNdty4gQE+yEq/Tj0cRHXmjzK2AYx0WYRAhWGNSTlTS\n4OJdjE6vsoPu7Ouz1R/i/egKniUifEXYSgyL+oPBUrqqsnk9lgGBkJipN3u1f9+K\niuUJJP/OZwKBgF6ZvqCcom0HPU5I7f+wu+vdVfA6yy45lHmLqAamSFw7cLBPI8Jh\nbI7jA9/Rgn9oipUmxcX34M/Eiq4u8Xp1qC4tP/16YMpaVU8qjY7ZdfB2b75lgdaT\npZLOxZsq9X8Xauso8uxv+nDCG/8YtmEV9d61u0acE+t+mA3PVxqkZ0m/AoGBAI5c\nY76AqeN+JVxaEm/0tIsj9Om46hR2URJ2lzB6YCuzINUqy9GjHJBWj9oITzD2FmNV\n/yCGIeW3CClOyCtzJyNLhYf5Sr+XjoKRQVN/+7+C/l2YL6Sg4Ok/PRMm6iH+u2QB\nJTY1d0pOdfUPqR8gKsVJgBGE04iwE/RmLpp9/XZRAoGAFtaa9JeHk9dmZiST3lev\ns5syeOK1cCj1+nJer/GPEjqWMKxbCULvoEYBp7RaoEXjfGi7P4Mc6YHnbljHc+sL\niJzHhxrv/HYZdlCdTU3IRWT0sNHzqZemfYnsVTSp+4y61sGDxioDYL4CLnMq5T2F\nqzfc2qp3s8ApVloY3giuqnI=\n-----END PRIVATE KEY-----\n", | |
| "client_email": "plan-maker@fynd-db.iam.gserviceaccount.com", | |
| "client_id": "114883060650442183907", | |
| "auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
| "token_uri": "https://oauth2.googleapis.com/token", | |
| "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
| "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/plan-maker%40fynd-db.iam.gserviceaccount.com", | |
| "universe_domain": "googleapis.com" | |
| } | |
| insert_into_bq(user_data, project_id, dataset_id, table_id, service_account_info) | |
| ###################################################### Single value ########################################################### | |
| elif bundle_by == "Single value": | |
| user_input_1 = st.sidebar.number_input("Enter Commercial value:") | |
| user_input_2 = float(user_input_1) | |
| st.session_state['user_input_3'] = "{:.2f}".format(user_input_2) | |
| plan_name = st.sidebar.text_input("Plan Name", help="Enter the name of the plan") | |
| plan_description = st.sidebar.text_area("Plan Description", max_chars=250, help="Describe the plan") | |
| plan_start_date = st.sidebar.date_input("Plan Start Date", value=datetime.now(), help="Select the start date of the plan") | |
| # Section 3: Defining products for each dropdown | |
| product_options = ["GoFynd", "Uniket", "ONDC", "StoreOS", "Website", "OMS", "WMS", "TMS", "GMC", "Partner", | |
| "Catalog Cloud", "FCP", "PixelBin", "Boltic", | |
| "CoPilot"] | |
| fee_type_options = ["Development", "Licensing", "Logistics", "Marketing", "Packaging", "Subscription", "Transaction"] | |
| fee_nature_options = ["Fixed %", "Flat currency", "Slab based", "As per rate card"] | |
| variable_options = ["Application", "Bag", "Extension", "Integration", "Order", "Platform", "Resource", "Shipment", "User", "B2B", "B2C"] | |
| chargeable_on_options = ["Active", "Build", "Cancelled", "Delivered", "DTO", "Invoiced", "Packed", "Picked", "Placed", "Return Window", "RTO", "Setup", "SiteOps-hr", "Subscribed", "TechOps-hr"] | |
| plan_validity_options = ["One time", "Monthly", "Quarterly", "Bi-Annually", "Annually"] | |
| payment_method_options = ["Prepaid", "Postpaid"] | |
| # Initialize session state variables if they don't exist | |
| if 'new_mapping' not in st.session_state: | |
| st.session_state['new_mapping'] = {} | |
| if 'file_data' not in st.session_state: | |
| st.session_state['file_data'] = None | |
| if 'mapping_mode' not in st.session_state: | |
| st.session_state['mapping_mode'] = None # None, 'default', 'custom' | |
| if 'button_clicked' not in st.session_state: | |
| st.session_state['button_clicked'] = None | |
| # Function to handle custom button click | |
| def custom_button_click(): | |
| st.session_state.button_clicked = 'custom' | |
| # Function to handle default button click | |
| def default_button_click(): | |
| st.session_state.button_clicked = 'default' | |
| # Display buttons without immediate execution on click | |
| col1, col2 = st.sidebar.columns([0.25, 0.45]) | |
| with col1: | |
| default_clicked = st.button("Default mapping") | |
| with col2: | |
| custom_clicked = st.button("Custom mapping") | |
| # Determine action based on button clicked | |
| if default_clicked: | |
| default_button_click() | |
| elif custom_clicked: | |
| custom_button_click() | |
| # Define CSS styles for the button | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| # Given new_mapping dictionary | |
| # Handle Default Mapping | |
| if st.session_state.button_clicked == 'default': | |
| new_mapping = { | |
| "GoFynd": { | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "Uniket": { | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "ONDC": { | |
| "Transaction": { | |
| "Bag": ["Return Window"], | |
| "Shipment": ["Cancelled", "RTO", "DTO"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "StoreOS": { | |
| "Licensing": { | |
| "Application": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Application": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Marketing": { | |
| "Order": ["Placed"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| } | |
| }, | |
| "Website": { | |
| "Licensing": { | |
| "Application": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Application": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| }, | |
| "Packaging": { | |
| "Shipment": ["Packed"] | |
| }, | |
| "Development": { | |
| "Application": ["Build"] | |
| } | |
| }, | |
| "OMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"] | |
| } | |
| }, | |
| "WMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Transaction": { | |
| "Order": ["Placed"], | |
| "Bag": ["Invoiced", "Delivered"], | |
| "B2B": ["Invoiced"], | |
| "B2C": ["Invoiced"] | |
| } | |
| }, | |
| "TMS": { | |
| "Development": { | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Integration": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Integration": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| }, | |
| "Logistics": { | |
| "Shipment": ["Picked", "RTO", "DTO"] | |
| } | |
| }, | |
| "GMC": { | |
| "Development": { | |
| "Extension": ["Build"], | |
| "Integration": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Partner": { | |
| "Development": { | |
| "Extension": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Catalog Cloud": { | |
| "Development": { | |
| "Extension": ["Build"] | |
| }, | |
| "Licensing": { | |
| "Extension": ["Setup"] | |
| }, | |
| "Subscription": { | |
| "Extension": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "FCP": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "PixelBin": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "Boltic": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| }, | |
| "CoPilot": { | |
| "Subscription": { | |
| "Platform": ["Subscribed"], | |
| "User": ["Active"], | |
| "Resource": ["TechOps-hr", "SiteOps-hr"] | |
| } | |
| } | |
| } | |
| st.session_state['new_mapping'] = new_mapping | |
| st.session_state['mapping_mode'] = 'default' | |
| html_content_1 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 22px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Section 2: Rule Info</h1> | |
| """ | |
| st.sidebar.markdown(html_content_1, unsafe_allow_html=True) | |
| # Handle Custom Mapping | |
| elif st.session_state.button_clicked == 'custom': | |
| # Define CSS styles for the button | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| # File upload | |
| uploaded_file = st.sidebar.file_uploader("Upload a file:", type=['csv', 'xlsx'], key='file_uploader') | |
| html_content_1 = """ | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 22px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Section 2: Rule Info</h1> | |
| """ | |
| st.sidebar.markdown(html_content_1, unsafe_allow_html=True) | |
| if uploaded_file is not None: | |
| try: | |
| # Read the file, treating the first row as the header | |
| if uploaded_file.name.endswith('.csv'): | |
| data = pd.read_csv(uploaded_file, header=0) | |
| elif uploaded_file.name.endswith('.xlsx'): | |
| data = pd.read_excel(uploaded_file, header=0) | |
| if st.sidebar.button("Overwrite headers"): | |
| # Rename the headers | |
| new_headers = ['ordering_channel', 'fee_type', 'variable_type', 'chargeable_on'] | |
| data.columns = new_headers | |
| # Save the data to session state | |
| st.session_state['file_data'] = data | |
| # Initialize the mapping | |
| new_mapping = {} | |
| # Build the mapping | |
| for _, row in data.iterrows(): | |
| ordering_channel = row['ordering_channel'] | |
| fee_type = row['fee_type'] | |
| variable_type = row['variable_type'] | |
| chargeable_on = row['chargeable_on'] | |
| if ordering_channel not in new_mapping: | |
| new_mapping[ordering_channel] = {} | |
| if fee_type not in new_mapping[ordering_channel]: | |
| new_mapping[ordering_channel][fee_type] = {} | |
| if variable_type not in new_mapping[ordering_channel][fee_type]: | |
| new_mapping[ordering_channel][fee_type][variable_type] = [] | |
| if chargeable_on not in new_mapping[ordering_channel][fee_type][variable_type]: | |
| new_mapping[ordering_channel][fee_type][variable_type].append(chargeable_on) | |
| st.session_state['new_mapping'] = new_mapping | |
| st.session_state['mapping_mode'] = 'custom' | |
| except Exception as e: | |
| st.error(f"Error reading the file: {e}") | |
| # Section 2: Company Info | |
| # Handle mapping display | |
| # Initialize session state variables if they don't exist | |
| # Initialize session state variables with default values if not already set | |
| if 'business_head' not in st.session_state: | |
| st.session_state['business_head'] = None | |
| if 'company_id' not in st.session_state: | |
| st.session_state['company_id'] = None | |
| if 'company_name' not in st.session_state: | |
| st.session_state['company_name'] = None | |
| if 'currency' not in st.session_state: | |
| st.session_state['currency'] = None | |
| if 'bundle_by' not in st.session_state: | |
| st.session_state['bundle_by'] = None | |
| if 'plan_name' not in st.session_state: | |
| st.session_state['plan_name'] = None | |
| if 'plan_description' not in st.session_state: | |
| st.session_state['plan_description'] = None | |
| if 'selected_ordering_channel' not in st.session_state: | |
| st.session_state['selected_ordering_channel'] = None | |
| if 'fulfilling_location' not in st.session_state: | |
| st.session_state['fulfilling_location'] = None | |
| if 'application_id' not in st.session_state: | |
| st.session_state['application_id'] = None | |
| if 'selected_fee_type' not in st.session_state: | |
| st.session_state['selected_fee_type'] = None | |
| if 'selected_variable_type' not in st.session_state: | |
| st.session_state['selected_variable_type'] = None | |
| if 'selected_chargeable_on' not in st.session_state: | |
| st.session_state['selected_chargeable_on'] = None | |
| if 'selected_fee_nature' not in st.session_state: | |
| st.session_state['selected_fee_nature'] = None | |
| if 'user_input_3' not in st.session_state: | |
| st.session_state['user_input_3'] = None | |
| if 'usage_3' not in st.session_state: | |
| st.session_state['usage_3'] = None | |
| if 'Capping_or_Minimum_Guarantee_3' not in st.session_state: | |
| st.session_state['Capping_or_Minimum_Guarantee_3'] = None | |
| if 'threshold' not in st.session_state: | |
| st.session_state['threshold'] = None | |
| if 'expected_billing' not in st.session_state: | |
| st.session_state['expected_billing'] = None | |
| if 'selected_payment_method' not in st.session_state: | |
| st.session_state['selected_payment_method'] = None | |
| if 'selected_plan_validity' not in st.session_state: | |
| st.session_state['selected_plan_validity'] = None | |
| if 'final_billing' not in st.session_state: | |
| st.session_state['final_billing'] = None | |
| if 'fee_reversal' not in st.session_state: | |
| st.session_state['fee_reversal'] = None | |
| if 'reversal_per' not in st.session_state: | |
| st.session_state['reversal_per'] = None | |
| # Check if 'mapping_mode' exists in session state before using it | |
| if 'mapping_mode' in st.session_state and st.session_state['mapping_mode']: | |
| # 1st layer: Select ordering channel | |
| selected_ordering_channel = st.sidebar.selectbox( | |
| "Product lines", | |
| [""] + list(st.session_state['new_mapping'].keys()), | |
| help="Select a Product line", | |
| key='ordering_channel' | |
| ) | |
| if selected_ordering_channel: | |
| selected_ordering_channel = str(selected_ordering_channel) or int(selected_ordering_channel) | |
| # Determine fulfilling_location and application_id based on selected_ordering_channel | |
| if any(channel in selected_ordering_channel for channel in ["TMS", "GMC", "Catalog Cloud"]): | |
| st.session_state['fulfilling_location'] = None | |
| st.session_state['application_id'] = None | |
| else: | |
| abc = ["Store", "Warehouse"] | |
| st.session_state['fulfilling_location'] = st.sidebar.selectbox( | |
| "Fulfilling Location", [""] + abc, help="Select the fulfilling location" | |
| ) | |
| st.session_state['application_id'] = st.sidebar.text_input( | |
| "Application ID", key="application_id_input", help="Enter the application ID" | |
| ) | |
| # Use the session state variables in your app | |
| fulfilling_location = st.session_state['fulfilling_location'] | |
| application_id = st.session_state['application_id'] | |
| # 2nd layer: Select fee type based on the selected ordering channel | |
| if 'selected_fee_type' not in st.session_state: | |
| st.session_state['selected_fee_type'] = None | |
| fee_types_for_channel = st.session_state['new_mapping'].get(selected_ordering_channel, {}).keys() | |
| fee_types_for_channel = list(fee_types_for_channel) | |
| if fee_types_for_channel: | |
| # Define selected_fee_type based on user input | |
| st.session_state['selected_fee_type'] = st.selectbox( | |
| "Fee Type", | |
| [""] + fee_types_for_channel, | |
| help="Fee type is a revenue head for grouping the revenue", | |
| key='fee_type' | |
| ) | |
| # Access selected_fee_type for any session state operations | |
| selected_fee_type = st.session_state['selected_fee_type'] | |
| # 3rd layer: Select variable type based on the selected fee type | |
| variable_type_options = [] | |
| if selected_fee_type: | |
| details = st.session_state['new_mapping'].get(selected_ordering_channel, {}) | |
| variables = details.get(selected_fee_type, {}) | |
| variable_type_options = list(variables.keys()) | |
| st.session_state['selected_variable_type'] = st.selectbox( | |
| "Variable Type", | |
| [""] + variable_type_options, | |
| help="Variable type is an attribute on which revenue calculation will be done", | |
| key='variable_type' | |
| ) | |
| selected_variable_type = st.session_state['selected_variable_type'] | |
| # 4th layer: Select chargeable on based on the selected variable type | |
| chargeable_on_options = [] | |
| if selected_variable_type: | |
| chargeable_on_options = variables.get(selected_variable_type, []) | |
| st.session_state['selected_chargeable_on'] = st.selectbox( | |
| "Chargeable on", | |
| [""] + chargeable_on_options, | |
| help="Chargeable on is a service status on which the above fee will be applicable", | |
| key='chargeable_on' | |
| ) | |
| selected_chargeable_on = st.session_state['selected_chargeable_on'] | |
| else: | |
| st.write("No fee types available for the selected ordering channel.") | |
| else: | |
| st.write("") | |
| selected_variable_type = st.session_state['selected_variable_type'] | |
| usage_1 = st.number_input(f"Usage limit for {selected_variable_type}", min_value=0.0, help="Enter the usage limit") | |
| usage_2 = float(usage_1) | |
| usage_3 = "{:.2f}".format(usage_2) | |
| expected_billing = user_input_1 | |
| html_content_8 = f""" | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 20px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Expected Monthly Billing (excluding GST): {expected_billing}</h1> | |
| """ | |
| # Using Streamlit to display the HTML content | |
| st.markdown(html_content_8, unsafe_allow_html=True) | |
| selected_plan_validity = st.selectbox("Plan Validity", [""] + plan_validity_options, help="Plan validity defines the periodicity of calculation for the above billing", key="plan_vd_2") | |
| selected_payment_method = st.selectbox("Payment Method", [""] + payment_method_options, help="Payment method defines the mode of payment of the plan", key="py_vd_2") | |
| initial_net_billing = 0 | |
| user_input_3 = st.session_state['user_input_3'] | |
| if selected_plan_validity == 'One time': | |
| final_billing = 1 * expected_billing | |
| elif selected_plan_validity == 'Monthly': | |
| final_billing = 1 * expected_billing | |
| elif selected_plan_validity == 'Quarterly': | |
| final_billing = 3 * expected_billing | |
| elif selected_plan_validity == 'Bi-Annually': | |
| final_billing = 6 * expected_billing | |
| elif selected_plan_validity == 'Annually': | |
| final_billing = 12 * expected_billing | |
| else: | |
| final_billing = initial_net_billing | |
| html_content_8 = f""" | |
| <h1 style=' | |
| color: #a689f6; | |
| font-size: 20px; | |
| background-image: -webkit-linear-gradient(0deg, #a689f6 3%, #272191 33%, #413bb9 61%); | |
| background-clip: text; | |
| -webkit-background-clip: text; | |
| text-fill-color: transparent; | |
| -webkit-text-fill-color: transparent; | |
| '>Net total billing (excluding GST): {final_billing}</h1> | |
| """ | |
| # Using Streamlit to display the HTML content | |
| st.markdown(html_content_8, unsafe_allow_html=True) | |
| button_styles = """ | |
| <style> | |
| div.stButton > button { | |
| color: #ffffff; /* Text color */ | |
| font-size: 50px; | |
| background-image: linear-gradient(0deg, #a689f6 3%, #413bb9 61%); | |
| border: none; | |
| padding: 10px 20px; | |
| cursor: pointer; | |
| border-radius: 15px; | |
| display: inline-block; | |
| } | |
| div.stButton > button:hover { | |
| background-color: #00ff00; /* Hover background color */ | |
| color: #ff0000; /* Hover text color */ | |
| } | |
| </style> | |
| """ | |
| # Render the button with the specified styles | |
| st.markdown(button_styles, unsafe_allow_html=True) | |
| rule_id = None | |
| plan_id = None | |
| # business_head = st.session_state['business_head'] | |
| company_name = st.session_state['company_name'] | |
| company_id = st.session_state['company_id'] | |
| # currency = st.session_state['currency'] | |
| # # bundle_by = st.session_state['bundle_by'] | |
| # plan_name = st.session_state['plan_name'] | |
| # plan_description = st.session_state['plan_description'] | |
| # selected_ordering_channel = st.session_state['selected_ordering_channel'] | |
| # fulfilling_location = st.session_state['fulfilling_location'] | |
| # application_id = st.session_state['application_id'] | |
| # selected_fee_type = st.session_state['selected_fee_type'] | |
| # selected_variable_type = st.session_state['selected_variable_type'] | |
| # selected_chargeable_on = st.session_state['selected_chargeable_on'] | |
| # user_input_3 = st.session_state['user_input_3'] | |
| # usage_3 = st.session_state['usage_3'] | |
| # Capping_or_Minimum_Guarantee_3 = st.session_state['Capping_or_Minimum_Guarantee_3'] | |
| # fee_reversal = st.session_state['fee_reversal'] | |
| # reversal_per = st.session_state['reversal_per'] | |
| # threshold = st.session_state['threshold'] | |
| # expected_billing = st.session_state['expected_billing'] | |
| # selected_payment_method = st.session_state['selected_payment_method'] | |
| # selected_plan_validity = st.session_state['selected_plan_validity'] | |
| # final_billing = int(st.session_state['final_billing']) if st.session_state['final_billing'] is not None else 0 | |
| # Submit button | |
| if st.button("Submit"): | |
| # Save user data | |
| user_data = { | |
| "Business Head": business_head, | |
| "Company ID": company_id.strip() if company_id else None, | |
| "Company Name": company_name, | |
| "Currency": currency, | |
| "Bundle by": bundle_by, | |
| "Plan Name": plan_name, | |
| "Plan Description": plan_description, | |
| "Product lines": selected_ordering_channel, | |
| "Fulfilling Location": fulfilling_location, | |
| "Application ID": application_id, | |
| "Fee Type": selected_fee_type, | |
| "Variable Type": selected_variable_type, | |
| "Chargeable on": selected_chargeable_on, | |
| "Fee Nature": 0, | |
| "Commercial value": user_input_3, | |
| "Fee reversal": 0, | |
| "Reversal %": 0, | |
| "Usage limit": usage_3, | |
| "Threshold value": 0, | |
| "Threshold option": 0, | |
| "Expected Billing": user_input_3, | |
| "Plan Validity": selected_plan_validity, | |
| "Payment Method": selected_payment_method, | |
| "Net_total_billing":int(final_billing) | |
| } | |
| # Generate rule_id and plan_id | |
| rule_id = generate_rule_id(user_data) | |
| plan_id = generate_plan_id(user_data) | |
| # Update user_data with generated IDs | |
| user_data['rule_id'] = rule_id | |
| user_data['plan_id'] = plan_id | |
| # Save the user data locally and to session state | |
| # global_user_data.append((user_name, user_data)) | |
| save_user_data(user_data) | |
| # Display saved records | |
| display_saved_records() | |
| # Store created_at, rule_id, and plan_id in session state | |
| st.session_state['created_at'] = datetime.now().isoformat() | |
| st.session_state['rule_id'] = rule_id | |
| st.session_state['plan_id'] = plan_id | |
| if st.button("Export data to BQ"): | |
| import logging | |
| from google.oauth2 import service_account | |
| from google.cloud import bigquery | |
| def insert_into_bq(user_data, project_id, dataset_id, table_id, service_account_info): | |
| try: | |
| # Use from_service_account_info instead of from_service_account_file | |
| credentials = service_account.Credentials.from_service_account_info(service_account_info) | |
| # Initialize a BigQuery client | |
| client = bigquery.Client(credentials=credentials, project=project_id) | |
| logging.info("BigQuery client initialized successfully.") | |
| # Specify the table reference | |
| table_ref = f"{project_id}.{dataset_id}.{table_id}" | |
| table = client.get_table(table_ref) | |
| logging.info(f"Table reference obtained: {table_ref}") | |
| # Insert form data into the table | |
| rows_to_insert = [user_data] | |
| errors = client.insert_rows_json(table, rows_to_insert) | |
| if errors: | |
| logging.error(f"Errors occurred while inserting rows: {errors}") | |
| st.error(f"Errors occurred while inserting rows: {errors}") | |
| else: | |
| logging.info("Insert successful") | |
| st.success("Insert successful") | |
| except Exception as e: | |
| logging.exception("An error occurred during the BigQuery insert operation.") | |
| st.error(f"An error occurred: {e}") | |
| project_id = "fynd-db" | |
| dataset_id = "finance_dwh" | |
| table_id = "plan_v2" | |
| fulfilling_location = st.session_state['fulfilling_location'] | |
| application_id = st.session_state['application_id'] | |
| # bundle_by = st.session_state['bundle_by'] | |
| # Retrieve created_at, rule_id, and plan_id from session state | |
| created_at = st.session_state.get('created_at') | |
| rule_id = st.session_state.get('rule_id') | |
| plan_id = st.session_state.get('plan_id') | |
| # Prepare user_data for BigQuery with correct rule_id and plan_id | |
| user_data = { | |
| "Business_Head": business_head, | |
| "Company_ID": company_id if company_id and company_id.strip() else None, | |
| "Company_Name": company_name, | |
| "Currency": currency, | |
| "Bundle_by": bundle_by, | |
| "Plan_Name": plan_name, | |
| "Plan_Description": plan_description, | |
| "Product_lines": selected_ordering_channel, | |
| "Fulfilling_Location": fulfilling_location, | |
| "Application_ID": application_id, | |
| "Fee_Type": selected_fee_type, | |
| "Variable_Type": selected_variable_type, | |
| "Chargeable_on": selected_chargeable_on, | |
| "Fee_Nature": 0, | |
| "Commercial_value": user_input_3, | |
| "Fee_reversal": 0, | |
| "Reversal_%": 0, | |
| "Usage_limit": usage_3, | |
| "Threshold_value": 0, | |
| "Threshold_option": 0, | |
| "Expected_Billing": user_input_3, | |
| "Payment_Method": selected_payment_method, | |
| "Plan_Validity": selected_plan_validity, | |
| "rule_id": rule_id, | |
| "plan_id": plan_id, | |
| "created_at": created_at, | |
| "Net_total_billing": int(final_billing) | |
| } | |
| save_user_data(user_data) | |
| service_account_info = { | |
| "type": "service_account", | |
| "project_id": "fynd-db", | |
| "private_key_id": "48954327ef172acc3091a91881840dc353ff0413", | |
| "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmIs0vgXflZmHD\n0IeHCiDEXavRb2GvRQqkCZGLy/EHFO7XLmpNrFzZHTSQach6HErARWTMsd2AMIA5\nHbmjEyt9deTOMUmICszkwNwpn6pzuoF2v4+fL2PQ4VBElLfCv4qbP9JGljvLsj5b\nC9UWe9rWgRrw2Z88LlVmFy3k4Om80Q57gW3hSYZpG4rBhC9+YRXjZ+Iq5SFEJQ+U\nj8ej7q6DnI8Prbvw/e13JH1pxm9AUQDm+sTsBmvjh4Ye02vKbfUP+pFOM0eC3Eoa\nOyG7unZnDuAaK9g87xVjd9HtD6MfaM0EHAEF1eyC4UqeiXTbVMwi7+0IGA2evEDZ\n3WRR2i+lAgMBAAECggEAF7Vis7NVsVqFfCS/moFTAMLfWLF87r67EIK/DwSpHloZ\n5YJdsDz3ORKmZC98aRSthDfC9UUyt270dXItAj0jmTFgWB6HgE8OQ1zUbmo3MHG+\ntPwMWmqwY2gsBMV2Xefot1QJxYH+AYkrxeFv5NgC+FaPSiy8QSHZlQqcxYtlP8kY\nzv8QFMgZ3b0sixK+YcSjCRXHu/DznnS/ZU7XlTALxANa50hT11rVLq6zYDF40fqC\nOWCOZvupjMOnNimXCWn7q6D1F8S/IMYlnHArJpEb7SdbJnJzxUvJC2rrMSoY896r\nyFEVhlElWp5GfTopu0WnL7iaw3pukM1OtpanFAk29wKBgQDW+yMzL7RiQ5LdElVP\n7Ml5hs+t6cjrUJTgBI8Uf9qGxE+tMe7Ye1fyJfbYslbOYO9xIUUT1jJmU6jadNWX\nA7UT59/IjvAOBIYyMEdh6Xo+H6ggW8DeU1HSdvixnQdgi0c03E6OCbOKi9E/UzK/\nTK2RBJJLN4MCiNL0FzrhTuxyEwKBgQDF1cz9Sb2UbrL5hr8LdcEH0ctatNlhJcSN\nnMd0Fn+e1EAkip+Hs9HmTvNdty4gQE+yEq/Tj0cRHXmjzK2AYx0WYRAhWGNSTlTS\n4OJdjE6vsoPu7Ouz1R/i/egKniUifEXYSgyL+oPBUrqqsnk9lgGBkJipN3u1f9+K\niuUJJP/OZwKBgF6ZvqCcom0HPU5I7f+wu+vdVfA6yy45lHmLqAamSFw7cLBPI8Jh\nbI7jA9/Rgn9oipUmxcX34M/Eiq4u8Xp1qC4tP/16YMpaVU8qjY7ZdfB2b75lgdaT\npZLOxZsq9X8Xauso8uxv+nDCG/8YtmEV9d61u0acE+t+mA3PVxqkZ0m/AoGBAI5c\nY76AqeN+JVxaEm/0tIsj9Om46hR2URJ2lzB6YCuzINUqy9GjHJBWj9oITzD2FmNV\n/yCGIeW3CClOyCtzJyNLhYf5Sr+XjoKRQVN/+7+C/l2YL6Sg4Ok/PRMm6iH+u2QB\nJTY1d0pOdfUPqR8gKsVJgBGE04iwE/RmLpp9/XZRAoGAFtaa9JeHk9dmZiST3lev\ns5syeOK1cCj1+nJer/GPEjqWMKxbCULvoEYBp7RaoEXjfGi7P4Mc6YHnbljHc+sL\niJzHhxrv/HYZdlCdTU3IRWT0sNHzqZemfYnsVTSp+4y61sGDxioDYL4CLnMq5T2F\nqzfc2qp3s8ApVloY3giuqnI=\n-----END PRIVATE KEY-----\n", | |
| "client_email": "plan-maker@fynd-db.iam.gserviceaccount.com", | |
| "client_id": "114883060650442183907", | |
| "auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
| "token_uri": "https://oauth2.googleapis.com/token", | |
| "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
| "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/plan-maker%40fynd-db.iam.gserviceaccount.com", | |
| "universe_domain": "googleapis.com" | |
| } | |
| insert_into_bq(user_data, project_id, dataset_id, table_id, service_account_info) | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| st.write(" ") | |
| # #Sidebar with an iframe | |
| # st.sidebar.markdown(""" | |
| # <style> | |
| # .left-aligned-iframe { | |
| # display: flex; | |
| # justify-content: flex-start; | |
| # width: 100%; | |
| # margin-top: 20px; /* Add a margin above the iframe */ | |
| # } | |
| # .left-aligned-iframe iframe { | |
| # width: 100%; /* Adjust width as needed */ | |
| # height: 800px; /* Adjust height as needed */ | |
| # border: none; | |
| # border-radius: 15px; | |
| # } | |
| # </style> | |
| # <div class="left-aligned-iframe"> | |
| # <iframe src="https://platform.fynd.com/blog" title="Fynd Platform"></iframe> | |
| # </div> | |
| # """, unsafe_allow_html=True) | |
| # Start a tunnel to the correct port | |
| # Connect to a port (e.g., 8501) without a custom subdomain | |
| # try: | |
| # ngrok_tunnel = ngrok.connect(8501) # Replace 8501 with your port number | |
| # print(f"ngrok tunnel URL: {ngrok_tunnel.public_url}") | |
| # except Exception as e: | |
| # print(f"Failed to start ngrok tunnel: {e}") | |