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 = """
Saved records
"""
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 = """
"""
# 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("""
""", unsafe_allow_html=True)
html_content = """
Plan maker
"""
st.markdown(html_content, unsafe_allow_html=True)
st.write(" ")
user_name = st.sidebar.text_input("Enter your name:")
html_content_1 = """
Section 1: Plan Info
"""
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 = """
"""
# 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 = """
Section 2: Rule Info
"""
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 = """
"""
# 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 = """
Section 2: Rule Info
"""
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"""
Expected Monthly Billing (excluding GST): {expected_billing}
"""
# 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"""
Net total billing (excluding GST): {final_billing}
"""
# 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 = """
"""
# 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 = """
"""
# 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 = """
Section 2: Rule Info
"""
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 = """
"""
# 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 = """
Section 2: Rule Info
"""
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"""
Expected Monthly Billing (excluding GST): {expected_billing}
"""
# 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"""
Net total billing (excluding GST): {final_billing}
"""
# Using Streamlit to display the HTML content
st.markdown(html_content_8, unsafe_allow_html=True)
button_styles = """
"""
# 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("""
#
#
#
#
# """, 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}")