Example #1
0
    def setUp(self):
        self._states = (
            'EXCESS_RANK',
            'SHORTAGE_RANK',
            'TRAFFIC_LIGHT',
            'CLASSIFICATION',
            'FORECAST',
            'RECOMMENDATION',
            'INVENTORY_TURNS',
            'START'
            )

        self.orders_analysis = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                                       z_value=Decimal(1.28),
                                                       reorder_cost=Decimal(5000),
                                                       file_type='csv',
                                                       length=12,
                                                       currency='USD')

        self.forecast = deserialise_config(ABS_FILE_PATH['FORECAST_PICKLE'])

        self.recommend = SkuMachine()
        self.states = SKUStates(analysed_orders=self.orders_analysis, forecast=self.forecast)
        self.recommend.add_state("start", self.states.initialise_machine)
        self.recommend.add_state("excess_rank", self.states.excess_rank)
        self.recommend.add_state("shortage_rank", self.states.shortage_rank)
        self.recommend.add_state("inventory_turns", self.states.inventory_turns)
        self.recommend.add_state("classification", self.states.classification)
        self.recommend.add_state("traffic_light", self.states.traffic_light)
        self.recommend.add_state("forecast", self.states.forecast)
        self.recommend.add_state("recommendation", self.recommend, end_state=1)
        self.recommend.set_start("start")
Example #2
0
def createSupplyChainAnalysis(pdesc):
    raw_df = createPdForAnalysis()
    orders_df = raw_df
    analyse_kv = dict(df=raw_df,
                      start=1,
                      interval_length=12,
                      interval_type='months',
                      z_value=Decimal(1.28),
                      reorder_cost=Decimal(400),
                      retail_price=Decimal(455),
                      file_type='csv',
                      currency='USD')
    print(raw_df)

    analysis_df = analyse(**analyse_kv)

    analysis_rev = analysis_df[['sku', 'revenue']]

    row_ds = raw_df[raw_df['Sku'] == pdesc].squeeze()
    ses = simple_exponential_smoothing_forecast(demand=list(row_ds[1:12]),
                                                alpha=0.5,
                                                forecast_length=6,
                                                initial_period=18)
    forecast_breakdown_df = pd.DataFrame(
        ses.get('forecast_breakdown', 'UNKNOWN'))
    regression = {
        'regression': [(ses.get('statistics')['slope'] * i) +
                       ses.get('statistics')['intercept']
                       for i in range(1, 12)]
    }
    print(regression)
    forecast_breakdown_df['regression'] = regression.get('regression')
    forecast_breakdown_df.plot(x='t',
                               y=['one_step_forecast', 'demand', 'regression'])
    plt.show()
 def test_abcxyz_classification(self):
     abc = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                                           z_value=Decimal(1.28),
                                                           reorder_cost=Decimal(5000),
                                                           file_type="csv")
     for sku in abc:
         item = sku.orders_summary()
         if item['sku'] == 'KR202-209':
             self.assertEqual(item['ABC_XYZ_Classification'], 'BY')
    def test_standard_deviation_row_count(self):
        d = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                    z_value=Decimal(1.28),
                                    reorder_cost=Decimal(400),
                                    retail_price=Decimal(455),
                                    file_type='csv')

        analysed_orders = [demand.orders_summary() for demand in d]

        self.assertEqual(len(d), 39)
Example #5
0
    def test_standard_deviation_row_count(self):
        d = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                    z_value=Decimal(1.28),
                                    reorder_cost=Decimal(400),
                                    retail_price=Decimal(455),
                                    file_type='csv')

        analysed_orders = [demand.orders_summary() for demand in d]

        self.assertEqual(len(d), 39)
Example #6
0
def simulation(runs: int = None):
    try:
        database_path = ''
        file_name = ''
        sim_results = []
        sim_summary_results = []
        inventory = []

        if runs is not None:
            config = deserialise_config(ABS_FILE_PATH_APPLICATION_CONFIG)
            database_path = config['database_path']
            file_name = config['file']
            file_path = database_path.replace(
                ' ', '') + '/' + (file_name.replace(' ', ''))
            analysed_orders = analyse(file_path=str(file_path),
                                      z_value=Decimal(1.28),
                                      reorder_cost=Decimal(5000),
                                      file_type=FileFormats.csv.name,
                                      length=12,
                                      currency='USD')
            # run the simulation, populate a database and then retrieve the most current values for the simulation page.
            try:
                with ThreadPoolExecutor(max_workers=1) as executor:
                    sim = executor.submit(simulate.run_monte_carlo,
                                          orders_analysis=analysed_orders,
                                          runs=runs,
                                          period_length=12)
                    sim_results = sim.result()
                    sim_window = executor.submit(simulate.summarize_window,
                                                 simulation_frame=sim_results,
                                                 period_length=12)
                    sim_window_result = sim_window.result()
                    sim_summary = executor.submit(simulate.summarise_frame,
                                                  sim_window_result)
                    sim_summary_results = sim_summary.result()
                    store_simulation(sim_summary_results)
                inventory = db.session.query(MasterSkuList).all()

            except OSError as e:
                print(e)
        elif runs is None and request.method == 'GET':
            try:
                sim_summary_results = select_last_simulation()
                inventory = db.session.query(MasterSkuList).all()
            except AttributeError as e:
                pass

        return flask.render_template('simulation.html',
                                     db=database_path,
                                     file_name=file_name,
                                     sim=sim_summary_results,
                                     runs=sim_results,
                                     inventory=inventory)
    except OSError:
        abort(404)
Example #7
0
 def test_data_frame(self):
     raw_df = pd.read_csv(ABS_FILE_PATH['COMPLETE_CSV_SM'])
     analysis_df = analyse(df=raw_df,
                           start=1,
                           interval_length=12,
                           interval_type='months')
     self.assertIsInstance(
         analysis_df[[
             'sku', 'quantity_on_hand', 'excess_stock', 'shortages',
             'ABC_XYZ_Classification'
         ]], DataFrame)
Example #8
0
    def setUp(self):
        self.orders_analysis = model_inventory.analyse(
            file_path=ABS_FILE_PATH['COMPLETE_CSV_XSM'],
            z_value=Decimal(1.28),
            reorder_cost=Decimal(5000),
            file_type="csv",
            length=12,
            currency='USD')

        self.cores = int(multiprocessing.cpu_count()) - 1
        self.batched_analysis = [
            i for i in batch(self.orders_analysis, self.cores)
        ]
    def setUp(self):
        self._z_value = Decimal(1.28)
        self._lead_time = Decimal(4)
        self._holding_cost_percentge = Decimal(0.25)
        self._retail_price = Decimal(5000)
        self._unit_cost = Decimal(55)
        self._reorder_cost = Decimal(450)
        self._quantity_on_hand = 1000
        self._backlog = 0

        self._data_set = {
            'jan': 25,
            'feb': 25,
            'mar': 25,
            'apr': 25,
            'may': 25,
            'jun': 25,
            'jul': 75,
            'aug': 75,
            'sep': 75,
            'oct': 75,
            'nov': 75,
            'dec': 75
        }

        self._orders_analysis = model_inventory.analyse(
            file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
            z_value=Decimal(1.28),
            reorder_cost=Decimal(5000),
            file_type="csv",
            length=12,
            currency='USD')

        self._uncertain_demand = analyse_uncertain_demand.UncertainDemand(
            self._data_set,
            sku='Rx493-90',
            lead_time=self._lead_time,
            reorder_cost=self._reorder_cost,
            z_value=self._z_value,
            holding_cost=self._holding_cost_percentge,
            retail_price=self._retail_price,
            unit_cost=self._unit_cost,
            currency='USD',
            quantity_on_hand=self._quantity_on_hand,
            backlog=0)
Example #10
0
def step_impl(context):
    """
    Args:
        context (behave.runner.Context): 
    """
    analyse_kv = dict(
        df=context.response,
        start=1,
        interval_length=12,
        interval_type='months',
        z_value=Decimal(1.28),
        reorder_cost=Decimal(400),
        retail_price=Decimal(455),
        file_type='csv',
        currency='USD'
    )
    analysis_df = analyse(**analyse_kv)
    context.response = analysis_df
    def setUp(self):
        self._data_set = {'jan': 25, 'feb': 25, 'mar': 25, 'apr': 25, 'may': 25, 'jun': 25, 'jul': 75,
                          'aug': 75, 'sep': 75, 'oct': 75, 'nov': 75, 'dec': 75}

        self._orders_analysis = model_inventory.analyse(
            file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
            z_value=Decimal(1.28),
            reorder_cost=Decimal(5000),
            file_type="csv",
            length=12)

        self._uncertain_demand = analyse_uncertain_demand.UncertainDemand(self._data_set,
                                                                          sku='Rx493-90',
                                                                          lead_time=Decimal(4),
                                                                          reorder_cost=Decimal(450),
                                                                          z_value=Decimal(1.28),
                                                                          holding_cost=Decimal(0.25),
                                                                          retail_price=Decimal(400.58),
                                                                          unit_cost=Decimal(55),
                                                                          currency='USD')
Example #12
0
    def setUp(self):
        self.STATES = ('EXCESS_RANK', 'SHORTAGE_RANK', 'TRAFFIC_LIGHT', 'CLASSIFICATION', 'FORECAST', 'RECOMMENDATION',
                       'INVENTORY_TURNS', 'START')

        self.orders_analysis = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                                       z_value=Decimal(1.28),
                                                       reorder_cost=Decimal(5000),
                                                       file_type="csv",
                                                       length=12)

        self.forecast = deserialise_config(ABS_FILE_PATH['FORECAST_PICKLE'])

        self.recommend = SkuMachine()
        self.states = SKUStates(analysed_orders=self.orders_analysis, forecast=self.forecast)
        self.recommend.add_state("start", self.states.initialise_machine)
        self.recommend.add_state("excess_rank", self.states.excess_rank)
        self.recommend.add_state("shortage_rank", self.states.shortage_rank)
        self.recommend.add_state("inventory_turns", self.states.inventory_turns)
        self.recommend.add_state("classification", self.states.classification)
        self.recommend.add_state("traffic_light", self.states.traffic_light)
        self.recommend.add_state("forecast", self.states.forecast)
        self.recommend.add_state("recommendation", self.recommend, end_state=1)
        self.recommend.set_start("start")
Example #13
0
    recommend.add_state("revenue", states.revenue)
    recommend.add_state("excess", states.excess)
    recommend.add_state("shortage", states.shortage)
    recommend.add_state("classification", states.classification)
    recommend.add_state("inventory", states.inventory_turns)
    recommend.add_state("recommendation", recommend, end_state=1)
    recommend.set_start("start")
    recommend.run()
    # have to serialise the profile recommendation seperately from the sku recommendation
    return deserialise_config(ABS_FILE_PATH['PROFILE_PICKLE'])


if __name__ == '__main__':
    orders_analysis = model_inventory.analyse(
        file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
        z_value=Decimal(1.28),
        reorder_cost=Decimal(5000),
        file_type="csv",
        length=12)

    # d = ProfileGenerator(analysed_orders=orders_analysis)
    # d.Top_Concerns()
    # resp = {}
    #for i in run_sku_recommendation(analysed_orders=orders_analysis, forecast=deserialise_config(FORECAST_PICKLE)).values():
    #   print(i)
    # d = ProfileStates(analysed_orders=orders_analysis, forecast=deserialise_config(FORECAST_PICKLE))
    # d.revenue()
    for i in run_profile_recommendation(
            analysed_orders=orders_analysis,
            forecast=deserialise_config(FORECAST_PICKLE)).values():
        print(i)
    recommend.add_state("start", states.initialise_machine)
    recommend.add_state("revenue", states.revenue)
    recommend.add_state("excess", states.excess)
    recommend.add_state("shortage", states.shortage)
    recommend.add_state("classification", states.classification)
    recommend.add_state("inventory", states.inventory_turns)
    recommend.add_state("recommendation", recommend, end_state=1)
    recommend.set_start("start")
    recommend.run()
    # have to serialise the profile recommendation seperately from the sku recommendation
    return deserialise_config(ABS_FILE_PATH['PROFILE_PICKLE'])


if __name__ == '__main__':
    orders_analysis = model_inventory.analyse(file_path=ABS_FILE_PATH['COMPLETE_CSV_SM'],
                                              z_value=Decimal(1.28),
                                              reorder_cost=Decimal(5000),
                                              file_type="csv",
                                              length=12)

    # d = ProfileGenerator(analysed_orders=orders_analysis)
    # d.Top_Concerns()
    # resp = {}
    #for i in run_sku_recommendation(analysed_orders=orders_analysis, forecast=deserialise_config(FORECAST_PICKLE)).values():
    #   print(i)
    # d = ProfileStates(analysed_orders=orders_analysis, forecast=deserialise_config(FORECAST_PICKLE))
    # d.revenue()
    for i in run_profile_recommendation(analysed_orders=orders_analysis,
                                        forecast=deserialise_config(FORECAST_PICKLE)).values():
        print(i)
Example #15
0
def load(file_path: str, location: str = None):
    """ Loads analysis and forecast into local database for reporting suite.

    Args:
        file_path (str):    File path to source file containing data for analysis.
        location (str):     Location of database to populate.

    """
    try:
        app = create_app()
        db.init_app(app)
        if location is not None and os.name in ['posix', 'mac']:
            app.config[
                'SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{}/reporting.db'.format(
                    location)

        elif location is not None and os.name == 'nt':
            app.config[
                'SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{}\\reporting.db'.format(
                    location)

        log.log(logging.DEBUG,
                'Loading data analysis for reporting suite... \n')
        with app.app_context():
            db.create_all()
            log.log(logging.DEBUG, 'loading currency symbols...\n')
            print('loading currency symbols...', end="")
            fx = currency_codes()
            load_currency(fx, db)

            print('[COMPLETED]\n')
            config = deserialise_config(ABS_FILE_PATH_APPLICATION_CONFIG)
            currency = config.get('currency')

            log.log(logging.DEBUG, 'Analysing file: {}...\n'.format(file_path))
            print('Analysing file: {}...'.format(file_path), end="")
            orders_analysis = model_inventory.analyse(
                file_path=file_path,
                z_value=Decimal(1.28),
                reorder_cost=Decimal(5000),
                file_type="csv",
                length=12,
                currency=currency)

            ia = [analysis.orders_summary() for analysis in orders_analysis]
            date_now = datetime.datetime.now()
            analysis_summary = Inventory(processed_orders=orders_analysis)
            print('[COMPLETED]\n')
            log.log(logging.DEBUG, 'Calculating Forecasts...\n')
            print('Calculating Forecasts...', end="")
            cores = int(multiprocessing.cpu_count())
            cores -= 1
            import multiprocessing as mp

            simple_forecast_gen = {}
            simple_forecast = {}
            with mp.Pool(processes=cores) as pool:
                simple_forecast_gen = ({
                    analysis.sku_id:
                    pool.apply_async(_analysis_forecast_simple,
                                     args=(analysis, ))
                } for analysis in orders_analysis)
                for gen in simple_forecast_gen:
                    simple_forecast.update(gen)
                simple_forecast = {
                    key: value.get()
                    for key, value in simple_forecast.items()
                }
                holts_forecast_gen = {
                    analysis.sku_id: pool.apply_async(_analysis_forecast_holt,
                                                      args=(analysis, ))
                    for analysis in orders_analysis
                }
                holts_forecast = {
                    key: holts_forecast_gen[key].get()
                    for key in holts_forecast_gen
                }

            # with ProcessPoolExecutor(max_workers=cores) as executor:
            #    simple_forecast_futures = { analysis.sku_id: executor.submit(_analysis_forecast_simple, analysis) for analysis in orders_analysis}
            #    simple_forecast_gen = {future: concurrent.futures.as_completed(simple_forecast_futures[future]) for future in simple_forecast_futures}
            #    simple_forecast = {value: simple_forecast_futures[value].result() for value in simple_forecast_gen}
            #    holts_forecast_futures = { analysis.sku_id: executor.submit(_analysis_forecast_holt, analysis) for analysis in orders_analysis}
            #    holts_forecast_gen = { future: concurrent.futures.as_completed(holts_forecast_futures[future]) for future in holts_forecast_futures}
            #    holts_forecast = {value: holts_forecast_futures[value].result() for value in holts_forecast_gen}
            #    executor.shutdown(wait=False)

            transact = TransactionLog()
            transact.date = date_now
            db.session.add(transact)
            db.session.commit()

            transaction_sub = db.session.query(db.func.max(
                TransactionLog.date))
            transaction_id = db.session.query(TransactionLog).filter(
                TransactionLog.date == transaction_sub).first()
            load_profile_recommendations(analysed_order=orders_analysis,
                                         forecast=holts_forecast,
                                         transaction_log_id=transaction_id)

            # d = _Orchestrate()
            # d.update_database(int(transaction_id.id))
            forecast_types = ('ses', 'htces')
            for f_type in forecast_types:
                forecast_type = ForecastType()
                forecast_type.type = f_type
                db.session.add(forecast_type)
            db.session.commit()
            ses_id = db.session.query(ForecastType.id).filter(
                ForecastType.type == forecast_types[0]).first()
            htces_id = db.session.query(ForecastType.id).filter(
                ForecastType.type == forecast_types[1]).first()
            print('[COMPLETED]\n')
            log.log(logging.DEBUG, 'loading database ...\n')
            print('loading database ...', end="")

            for item in ia:
                re = 0
                skus_description = [
                    summarised for summarised in analysis_summary.describe_sku(
                        item['sku'])
                ]
                denom = db.session.query(Currency.id).filter(
                    Currency.currency_code == item['currency']).first()
                master_sku = MasterSkuList()
                master_sku.sku_id = item['sku']
                db.session.add(master_sku)
                i_up = InventoryAnalysis()
                mk = db.session.query(MasterSkuList.id).filter(
                    MasterSkuList.sku_id == item['sku']).first()
                i_up.sku_id = mk.id
                tuple_orders = item['orders']
                # print(tuple_orders)
                i_up.abc_xyz_classification = item['ABC_XYZ_Classification']
                i_up.standard_deviation = item['standard_deviation']
                i_up.backlog = item['backlog']
                i_up.safety_stock = item['safety_stock']
                i_up.reorder_level = item['reorder_level']
                i_up.economic_order_quantity = item['economic_order_quantity']
                i_up.demand_variability = item['demand_variability']
                i_up.average_orders = round(float(item['average_orders']))
                i_up.shortages = item['shortages']
                i_up.excess_stock = item['excess_stock']
                i_up.reorder_quantity = item['reorder_quantity']
                i_up.economic_order_variable_cost = item[
                    'economic_order_variable_cost']
                i_up.unit_cost = item['unit_cost']
                i_up.revenue = item['revenue']
                i_up.date = date_now
                i_up.safety_stock_rank = skus_description[0][
                    'safety_stock_rank']
                i_up.shortage_rank = skus_description[0]['shortage_rank']
                i_up.excess_cost = skus_description[0]['excess_cost']
                i_up.percentage_contribution_revenue = skus_description[0][
                    'percentage_contribution_revenue']
                i_up.excess_rank = skus_description[0]['excess_rank']
                i_up.retail_price = skus_description[0]['retail_price']
                i_up.gross_profit_margin = skus_description[0][
                    'gross_profit_margin']
                i_up.min_order = skus_description[0]['min_order']
                i_up.safety_stock_cost = skus_description[0][
                    'safety_stock_cost']
                i_up.revenue_rank = skus_description[0]['revenue_rank']
                i_up.markup_percentage = skus_description[0][
                    'markup_percentage']
                i_up.max_order = skus_description[0]['max_order']
                i_up.shortage_cost = skus_description[0]['shortage_cost']
                i_up.quantity_on_hand = item['quantity_on_hand']
                i_up.currency_id = denom.id
                i_up.traffic_light = skus_description[0][
                    'inventory_traffic_light']
                i_up.inventory_turns = skus_description[0]['inventory_turns']
                i_up.transaction_log_id = transaction_id.id
                db.session.add(i_up)
                inva = db.session.query(InventoryAnalysis.id).filter(
                    InventoryAnalysis.sku_id == mk.id).first()
                for i, t in enumerate(tuple_orders['demand'], 1):
                    orders_data = Orders()
                    # print(r)
                    orders_data.order_quantity = t
                    orders_data.rank = i
                    orders_data.analysis_id = inva.id
                    db.session.add(orders_data)
                    # need to select sku id
                for i, forecasted_demand in enumerate(simple_forecast, 1):
                    if forecasted_demand == item['sku']:
                        forecast_stats = ForecastStatistics()
                        forecast_stats.analysis_id = inva.id
                        forecast_stats.mape = simple_forecast.get(
                            forecasted_demand)['mape']
                        forecast_stats.forecast_type_id = ses_id.id
                        forecast_stats.slope = simple_forecast.get(
                            forecasted_demand)['statistics']['slope']
                        forecast_stats.p_value = simple_forecast.get(
                            forecasted_demand)['statistics']['pvalue']
                        forecast_stats.test_statistic = simple_forecast.get(
                            forecasted_demand)['statistics']['test_statistic']
                        forecast_stats.slope_standard_error = simple_forecast.get(
                            forecasted_demand
                        )['statistics']['slope_standard_error']
                        forecast_stats.intercept = simple_forecast.get(
                            forecasted_demand)['statistics']['intercept']
                        forecast_stats.standard_residuals = simple_forecast.get(
                            forecasted_demand)['statistics']['std_residuals']
                        forecast_stats.trending = simple_forecast.get(
                            forecasted_demand)['statistics']['trend']
                        forecast_stats.optimal_alpha = simple_forecast.get(
                            forecasted_demand)['optimal_alpha']
                        forecast_stats.optimal_gamma = 0
                        db.session.add(forecast_stats)
                        for p in range(
                                0,
                                len(
                                    simple_forecast.get(forecasted_demand)
                                    ['forecast'])):
                            forecast_data = Forecast()
                            forecast_data.forecast_quantity = simple_forecast.get(
                                forecasted_demand)['forecast'][p]
                            forecast_data.analysis_id = inva.id
                            forecast_data.forecast_type_id = ses_id.id
                            forecast_data.period = p + 1
                            forecast_data.create_date = date_now
                            db.session.add(forecast_data)
                        for q, sesf in enumerate(
                                simple_forecast.get(forecasted_demand)
                            ['forecast_breakdown']):
                            forecast_breakdown = ForecastBreakdown()
                            forecast_breakdown.analysis_id = inva.id
                            forecast_breakdown.forecast_type_id = ses_id.id
                            forecast_breakdown.trend = 0
                            forecast_breakdown.period = sesf['t']
                            forecast_breakdown.level_estimates = \
                                sesf['level_estimates']
                            forecast_breakdown.one_step_forecast = \
                                sesf['one_step_forecast']
                            forecast_breakdown.forecast_error = \
                                sesf['forecast_error']
                            forecast_breakdown.squared_error = sesf[
                                'squared_error']
                            forecast_breakdown.regression = simple_forecast.get(
                                forecasted_demand)['regression'][q]
                            db.session.add(forecast_breakdown)
                        break

                for i, holts_forecast_demand in enumerate(holts_forecast, 1):
                    if holts_forecast_demand == item['sku']:
                        forecast_stats = ForecastStatistics()
                        forecast_stats.analysis_id = inva.id
                        forecast_stats.mape = holts_forecast.get(
                            holts_forecast_demand)['mape']
                        forecast_stats.forecast_type_id = htces_id.id
                        forecast_stats.slope = holts_forecast.get(
                            holts_forecast_demand)['statistics']['slope']
                        forecast_stats.p_value = holts_forecast.get(
                            holts_forecast_demand)['statistics']['pvalue']
                        forecast_stats.test_statistic = holts_forecast.get(
                            holts_forecast_demand
                        )['statistics']['test_statistic']
                        forecast_stats.slope_standard_error = holts_forecast.get(
                            holts_forecast_demand
                        )['statistics']['slope_standard_error']
                        forecast_stats.intercept = holts_forecast.get(
                            holts_forecast_demand)['statistics']['intercept']
                        forecast_stats.standard_residuals = holts_forecast.get(
                            holts_forecast_demand
                        )['statistics']['std_residuals']
                        forecast_stats.trending = holts_forecast.get(
                            holts_forecast_demand)['statistics']['trend']
                        forecast_stats.optimal_alpha = holts_forecast.get(
                            holts_forecast_demand)['optimal_alpha']
                        forecast_stats.optimal_gamma = holts_forecast.get(
                            holts_forecast_demand)['optimal_gamma']
                        db.session.add(forecast_stats)
                        for p in range(
                                0,
                                len(
                                    holts_forecast.get(holts_forecast_demand)
                                    ['forecast'])):
                            forecast_data = Forecast()
                            forecast_data.forecast_quantity = holts_forecast.get(
                                holts_forecast_demand)['forecast'][p]
                            forecast_data.analysis_id = inva.id
                            forecast_data.forecast_type_id = htces_id.id
                            forecast_data.period = p + 1
                            forecast_data.create_date = date_now
                            db.session.add(forecast_data)
                        for i, htcesf in enumerate(
                                holts_forecast.get(holts_forecast_demand)
                            ['forecast_breakdown']):
                            forecast_breakdown = ForecastBreakdown()
                            forecast_breakdown.analysis_id = inva.id
                            forecast_breakdown.forecast_type_id = htces_id.id
                            forecast_breakdown.trend = htcesf['trend']
                            forecast_breakdown.period = htcesf['t']
                            forecast_breakdown.level_estimates = \
                                htcesf['level_estimates']
                            forecast_breakdown.one_step_forecast = \
                                htcesf['one_step_forecast']
                            forecast_breakdown.forecast_error = \
                                htcesf['forecast_error']
                            forecast_breakdown.squared_error = htcesf[
                                'squared_error']
                            forecast_breakdown.regression = holts_forecast.get(
                                holts_forecast_demand)['regression'][i]
                            db.session.add(forecast_breakdown)
                        break

            db.session.commit()
            print('[COMPLETED]\n')
            loading = 'Loading recommendations into database... '
            print(loading, end="")
            load_recommendations(summary=ia,
                                 forecast=holts_forecast,
                                 analysed_order=orders_analysis)
            print('[COMPLETED]\n')
            log.log(logging.DEBUG, "Analysis ...\n")
            print("Analysis ... [COMPLETED]")
    except OSError as e:
        print(e)
Example #16
0
def load(file_path: str, location: str = None):
    if location is not None and os.name in ['posix', 'mac']:
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{}/reporting.db'.format(location)

    elif location is not None and os.name == 'nt':
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{}\\reporting.db'.format(location)

    log.log(logging.DEBUG, 'Loading data analysis for reporting suite... \n')

    db.create_all()

    log.log(logging.DEBUG, 'loading currency symbols...\n')
    print('loading currency symbols...', end="")
    fx = currency_codes()
    for key, value in fx.items():
        codes = Currency()
        codes.country = value[0]
        codes.symbol = value[1]
        codes.currency_code = key
        db.session.add(codes)
    db.session.commit()
    print('[COMPLETED]\n')
    config = deserialise_config(ABS_FILE_PATH_APPLICATION_CONFIG)
    currency = config.get('currency')

    log.log(logging.DEBUG, 'Analysing file: {}...\n'.format(file_path))
    print('Analysing file: {}...'.format(file_path), end="")
    orders_analysis = model_inventory.analyse(file_path=file_path,
                                              z_value=Decimal(1.28),
                                              reorder_cost=Decimal(5000),
                                              file_type="csv", length=12,currency=currency)

    # remove assumption file type is csv

    ia = [analysis.orders_summary() for analysis in
          model_inventory.analyse(file_path=file_path, z_value=Decimal(1.28),
                                  reorder_cost=Decimal(5000), file_type="csv", length=12, currency=currency)]
    date_now = datetime.datetime.now()
    analysis_summary = Inventory(processed_orders=orders_analysis)
    print('[COMPLETED]\n')

    log.log(logging.DEBUG, 'Calculating Forecasts...\n')
    print('Calculating Forecasts...', end="")
    simple_forecast = {analysis.sku_id: analysis.simple_exponential_smoothing_forecast for analysis in
                       model_inventory.analyse(file_path=file_path, z_value=Decimal(1.28),
                                               reorder_cost=Decimal(5000), file_type="csv",
                                               length=12, currency=currency)}
    holts_forecast = {analysis.sku_id: analysis.holts_trend_corrected_forecast for analysis in
                      model_inventory.analyse(file_path=file_path, z_value=Decimal(1.28),
                                              reorder_cost=Decimal(5000), file_type="csv",
                                              length=12,currency=currency)}

    transact = TransactionLog()
    transact.date = date_now
    db.session.add(transact)
    db.session.commit()

    transaction_sub = db.session.query(db.func.max(TransactionLog.date))
    transaction_id = db.session.query(TransactionLog).filter(TransactionLog.date == transaction_sub).first()

    # loads inventory profile recommendations
    load_profile_recommendations(analysed_order=orders_analysis, forecast=holts_forecast,
                                 transaction_log_id=transaction_id)

    #d = _Orchestrate()
    #d.update_database(int(transaction_id.id))

    forecast_types = ('ses', 'htces')

    for f_type in forecast_types:
        forecast_type = ForecastType()
        forecast_type.type = f_type
        db.session.add(forecast_type)
    db.session.commit()
    ses_id = db.session.query(ForecastType.id).filter(ForecastType.type == forecast_types[0]).first()
    htces_id = db.session.query(ForecastType.id).filter(ForecastType.type == forecast_types[1]).first()
    print('[COMPLETED]\n')
    log.log(logging.DEBUG, 'loading database ...\n')
    print('loading database ...', end="")

    for item in ia:
        re = 0
        skus_description = [summarised for summarised in analysis_summary.describe_sku(item['sku'])]
        denom = db.session.query(Currency.id).filter(Currency.currency_code == item['currency']).first()
        master_sku = MasterSkuList()
        master_sku.sku_id = item['sku']
        db.session.add(master_sku)
        i_up = InventoryAnalysis()
        mk = db.session.query(MasterSkuList.id).filter(MasterSkuList.sku_id == item['sku']).first()
        i_up.sku_id = mk.id
        tuple_orders = item['orders']
        # print(tuple_orders)
        i_up.abc_xyz_classification = item['ABC_XYZ_Classification']
        i_up.standard_deviation = item['standard_deviation']
        i_up.backlog = item['backlog']
        i_up.safety_stock = item['safety_stock']
        i_up.reorder_level = item['reorder_level']
        i_up.economic_order_quantity = item['economic_order_quantity']
        i_up.demand_variability = item['demand_variability']
        i_up.average_orders = round(float(item['average_orders']))
        i_up.shortages = item['shortages']
        i_up.excess_stock = item['excess_stock']
        i_up.reorder_quantity = item['reorder_quantity']
        i_up.economic_order_variable_cost = item['economic_order_variable_cost']
        i_up.unit_cost = item['unit_cost']
        i_up.revenue = item['revenue']
        i_up.date = date_now
        i_up.safety_stock_rank = skus_description[0]['safety_stock_rank']
        i_up.shortage_rank = skus_description[0]['shortage_rank']
        i_up.excess_cost = skus_description[0]['excess_cost']
        i_up.percentage_contribution_revenue = skus_description[0]['percentage_contribution_revenue']
        i_up.excess_rank = skus_description[0]['excess_rank']
        i_up.retail_price = skus_description[0]['retail_price']
        i_up.gross_profit_margin = skus_description[0]['gross_profit_margin']
        i_up.min_order = skus_description[0]['min_order']
        i_up.safety_stock_cost = skus_description[0]['safety_stock_cost']
        i_up.revenue_rank = skus_description[0]['revenue_rank']
        i_up.markup_percentage = skus_description[0]['markup_percentage']
        i_up.max_order = skus_description[0]['max_order']
        i_up.shortage_cost = skus_description[0]['shortage_cost']
        i_up.quantity_on_hand = item['quantity_on_hand']
        i_up.currency_id = denom.id
        i_up.traffic_light = skus_description[0]['inventory_traffic_light']
        i_up.inventory_turns = skus_description[0]['inventory_turns']
        i_up.transaction_log_id = transaction_id.id
        db.session.add(i_up)
        inva = db.session.query(InventoryAnalysis.id).filter(InventoryAnalysis.sku_id == mk.id).first()
        for i, t in enumerate(tuple_orders['demand'], 1):
            orders_data = Orders()
            # print(r)
            orders_data.order_quantity = t
            orders_data.rank = i
            orders_data.analysis_id = inva.id
            db.session.add(orders_data)
            # need to select sku id
        for i, forecasted_demand in enumerate(simple_forecast, 1):
            if forecasted_demand == item['sku']:
                forecast_stats = ForecastStatistics()
                forecast_stats.analysis_id = inva.id
                forecast_stats.mape = simple_forecast.get(forecasted_demand)['mape']
                forecast_stats.forecast_type_id = ses_id.id
                forecast_stats.slope = simple_forecast.get(forecasted_demand)['statistics']['slope']
                forecast_stats.p_value = simple_forecast.get(forecasted_demand)['statistics']['pvalue']
                forecast_stats.test_statistic = simple_forecast.get(forecasted_demand)['statistics']['test_statistic']
                forecast_stats.slope_standard_error = simple_forecast.get(forecasted_demand)['statistics'][
                    'slope_standard_error']
                forecast_stats.intercept = simple_forecast.get(forecasted_demand)['statistics']['intercept']
                forecast_stats.standard_residuals = simple_forecast.get(forecasted_demand)['statistics'][
                    'std_residuals']
                forecast_stats.trending = simple_forecast.get(forecasted_demand)['statistics']['trend']
                forecast_stats.optimal_alpha = simple_forecast.get(forecasted_demand)['optimal_alpha']
                forecast_stats.optimal_gamma = 0
                db.session.add(forecast_stats)
                for p in range(0, len(simple_forecast.get(forecasted_demand)['forecast'])):
                    forecast_data = Forecast()
                    forecast_data.forecast_quantity = simple_forecast.get(forecasted_demand)['forecast'][p]
                    forecast_data.analysis_id = inva.id
                    forecast_data.forecast_type_id = ses_id.id
                    forecast_data.period = p + 1
                    forecast_data.create_date = date_now
                    db.session.add(forecast_data)
                for q, sesf in enumerate(simple_forecast.get(forecasted_demand)['forecast_breakdown']):
                    forecast_breakdown = ForecastBreakdown()
                    forecast_breakdown.analysis_id = inva.id
                    forecast_breakdown.forecast_type_id = ses_id.id
                    forecast_breakdown.trend = 0
                    forecast_breakdown.period = sesf['t']
                    forecast_breakdown.level_estimates = \
                        sesf['level_estimates']
                    forecast_breakdown.one_step_forecast = \
                        sesf['one_step_forecast']
                    forecast_breakdown.forecast_error = \
                        sesf['forecast_error']
                    forecast_breakdown.squared_error = sesf['squared_error']
                    forecast_breakdown.regression = simple_forecast.get(forecasted_demand)['regression'][q]
                    db.session.add(forecast_breakdown)
                break
        for i, holts_forecast_demand in enumerate(holts_forecast, 1):
            if holts_forecast_demand == item['sku']:
                forecast_stats = ForecastStatistics()
                forecast_stats.analysis_id = inva.id
                forecast_stats.mape = holts_forecast.get(holts_forecast_demand)['mape']
                forecast_stats.forecast_type_id = htces_id.id
                forecast_stats.slope = holts_forecast.get(holts_forecast_demand)['statistics']['slope']
                forecast_stats.p_value = holts_forecast.get(holts_forecast_demand)['statistics']['pvalue']
                forecast_stats.test_statistic = holts_forecast.get(holts_forecast_demand)['statistics'][
                    'test_statistic']
                forecast_stats.slope_standard_error = holts_forecast.get(holts_forecast_demand)['statistics'][
                    'slope_standard_error']
                forecast_stats.intercept = holts_forecast.get(holts_forecast_demand)['statistics']['intercept']
                forecast_stats.standard_residuals = holts_forecast.get(holts_forecast_demand)['statistics'][
                    'std_residuals']
                forecast_stats.trending = holts_forecast.get(holts_forecast_demand)['statistics']['trend']
                forecast_stats.optimal_alpha = holts_forecast.get(holts_forecast_demand)['optimal_alpha']
                forecast_stats.optimal_gamma = holts_forecast.get(holts_forecast_demand)['optimal_gamma']
                db.session.add(forecast_stats)
                for p in range(0, len(holts_forecast.get(holts_forecast_demand)['forecast'])):
                    forecast_data = Forecast()
                    forecast_data.forecast_quantity = holts_forecast.get(holts_forecast_demand)['forecast'][p]
                    forecast_data.analysis_id = inva.id
                    forecast_data.forecast_type_id = htces_id.id
                    forecast_data.period = p + 1
                    forecast_data.create_date = date_now
                    db.session.add(forecast_data)
                for i, htcesf in enumerate(holts_forecast.get(holts_forecast_demand)['forecast_breakdown']):
                    forecast_breakdown = ForecastBreakdown()
                    forecast_breakdown.analysis_id = inva.id
                    forecast_breakdown.forecast_type_id = htces_id.id
                    forecast_breakdown.trend = htcesf['trend']
                    forecast_breakdown.period = htcesf['t']
                    forecast_breakdown.level_estimates = \
                        htcesf['level_estimates']
                    forecast_breakdown.one_step_forecast = \
                        htcesf['one_step_forecast']
                    forecast_breakdown.forecast_error = \
                        htcesf['forecast_error']
                    forecast_breakdown.squared_error = htcesf['squared_error']
                    forecast_breakdown.regression = holts_forecast.get(holts_forecast_demand)['regression'][i]
                    db.session.add(forecast_breakdown)
                break

    db.session.commit()
    print('[COMPLETED]\n')
    loading = 'Loading recommendations into database... '
    print(loading, end="")
    load_recommendations(summary=ia, forecast=holts_forecast, analysed_order=orders_analysis)
    print('[COMPLETED]\n')
    log.log(logging.DEBUG, "Analysis ...\n")
    print("Analysis ... [COMPLETED]")
 def test_data_frame(self):
     raw_df = pd.read_csv(ABS_FILE_PATH['COMPLETE_CSV_SM'])
     analysis_df = analyse(df=raw_df, start=1, interval_length=12, interval_type='months')
     self.assertIsInstance(analysis_df[['sku', 'quantity_on_hand', 'excess_stock', 'shortages', 'ABC_XYZ_Classification']], DataFrame)