File size: 5,596 Bytes
8c47c78
 
 
 
b335a84
c3b38ee
8c47c78
 
c3b38ee
 
 
 
 
 
 
 
 
 
 
 
51c17e5
c3b38ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c47c78
c3b38ee
 
8c47c78
c3b38ee
 
8c47c78
b335a84
8c47c78
b335a84
 
8c47c78
 
b335a84
 
 
8c47c78
b335a84
8c47c78
 
b335a84
8c47c78
 
b335a84
 
 
 
 
8c47c78
 
b335a84
 
 
351ad2c
b335a84
 
351ad2c
b335a84
 
351ad2c
8c47c78
b335a84
 
 
 
 
 
 
 
 
 
 
 
 
8c47c78
 
 
 
 
 
 
 
 
 
b335a84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c47c78
 
b335a84
8c47c78
b335a84
8c47c78
 
 
b335a84
8c47c78
 
 
 
b335a84
8c47c78
 
 
 
 
b335a84
c3b38ee
8c47c78
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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':'user@123',
      'password':'user@123',
      'client_secret':'kNqJjlPkxyHdIKt3szCt4PYFWtFOdUheb8QVN8vQ',
      'client_id':'5',
      '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}<br>Forecasted Sales: %{y}<extra></extra>'
    ))

    # 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()