import pandas as pd
from prophet import Prophet
import gradio as gr
import plotly.graph_objs as go
import numpy as np
import requests
# Function to train the model and generate forecast
def predict_sales(time_frame):
#login
url="https://livesystem.hisabkarlay.com/auth/login"
payload={
'username':'testuser',
'password':'testuser',
'client_secret':'3udPXhYSfCpktnls1C3TSzI96JLypqUGwJR05RHf',
'client_id':'4',
'grant_type':'password'
}
response=requests.post(url,data=payload)
print(response.text)
access_token=response.json()['access_token']
print(access_token)
#fetch all sell data
per_page=-1
url=f"https://livesystem.hisabkarlay.com/connector/api/sell?per_page={per_page}"
headers={
'Authorization':f'Bearer {access_token}'
}
response=requests.get(url,headers=headers)
data=response.json()['data']
date=[]
amount=[]
for item in data:
date.append(item.get('transaction_date'))
amount.append(float(item.get('final_total')))
data_dict={
'date':date,
'amount':amount
}
data_frame=pd.DataFrame(data_dict)
# Convert 'date' column to datetime format
data_frame['date'] = pd.to_datetime(data_frame['date'])
# Extract only the date part
data_frame['date_only'] = data_frame['date'].dt.date
# Group by date and calculate total sales
daily_sales = data_frame.groupby('date_only').agg(total_sales=('amount', 'sum')).reset_index()
# Prepare the DataFrame for Prophet
df = pd.DataFrame({
'Date': daily_sales['date_only'],
'Total paid': daily_sales['total_sales']
})
# Apply log transformation
df['y'] = np.log1p(df['Total paid']) # Using log1p to avoid log(0)
# Prepare Prophet model
model = Prophet(weekly_seasonality=True) # Enable weekly seasonality
df['ds'] = df['Date']
model.fit(df[['ds', 'y']])
# Future forecast based on the time frame
future_periods = {
'Next Day': 1,
'7 days': 7,
'10 days': 10,
'15 days': 15,
'1 month': 30
}
# Get the last historical date and calculate the start date for the forecast
last_date_value = df['Date'].iloc[-1]
forecast_start_date = pd.Timestamp(last_date_value) + pd.Timedelta(days=1) # Start the forecast from the next day
# Generate the future time DataFrame starting from the day after the last date
future_time = model.make_future_dataframe(periods=future_periods[time_frame], freq='D')
# Filter future_time to include only future dates starting from forecast_start_date
future_only = future_time[future_time['ds'] >= forecast_start_date]
forecast = model.predict(future_only)
# Exponentiate the forecast to revert back to the original scale
forecast['yhat'] = np.expm1(forecast['yhat']) # Use expm1 to handle the log transformation
forecast['yhat_lower'] = np.expm1(forecast['yhat_lower']) # Exponentiate lower bound
forecast['yhat_upper'] = np.expm1(forecast['yhat_upper']) # Exponentiate upper bound
# Create a DataFrame for weekends only
forecast['day_of_week'] = forecast['ds'].dt.day_name() # Get the day name from the date
weekends = forecast[forecast['day_of_week'].isin(['Saturday', 'Sunday'])] # Filter for weekends
# Display the forecasted data for the specified period
forecast_table = forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head(future_periods[time_frame])
weekend_forecast_table = weekends[['ds', 'yhat', 'yhat_lower', 'yhat_upper']] # Weekend forecast
# Create a Plotly graph
fig = go.Figure()
fig.add_trace(go.Scatter(
x=forecast['ds'], y=forecast['yhat'],
mode='lines+markers',
name='Forecasted Sales',
line=dict(color='orange'),
marker=dict(size=6),
hovertemplate='Date: %{x}
Forecasted Sales: %{y}'
))
# Add lines for yhat_lower and yhat_upper
fig.add_trace(go.Scatter(
x=forecast['ds'], y=forecast['yhat_lower'],
mode='lines',
name='Lower Bound',
line=dict(color='red', dash='dash')
))
fig.add_trace(go.Scatter(
x=forecast['ds'], y=forecast['yhat_upper'],
mode='lines',
name='Upper Bound',
line=dict(color='green', dash='dash')
))
fig.update_layout(
title='Sales Forecast using Prophet',
xaxis_title='Date',
yaxis_title='Sales Price',
xaxis=dict(tickformat="%Y-%m-%d"),
yaxis=dict(autorange=True)
)
return forecast_table, weekend_forecast_table, fig # Return the forecast table, weekend forecast, and plot
# Gradio interface
def run_gradio():
# Create the Gradio Interface
time_options = ['Next Day', '7 days', '10 days', '15 days', '1 month']
gr.Interface(
fn=predict_sales, # Function to be called
inputs=gr.components.Dropdown(time_options, label="Select Forecast Time Range"), # User input
outputs=[
gr.components.Dataframe(label="Forecasted Sales Table"), # Forecasted data in tabular form
gr.components.Dataframe(label="Weekend Forecasted Sales Table"), # Weekend forecast data
gr.components.Plot(label="Sales Forecast Plot",min_width=500,scale=2) # Plotly graph output
],
title="Sales Forecasting with Prophet",
description="Select a time range for the forecast and click on the button to train the model and see the results."
).launch(debug=True)
# Run the Gradio interface
if __name__ == '__main__':
run_gradio()