Beispiel #1
0
        public static async Task <Result <CurrencyRate> > GetRate(string currency, DateTime date)
        {
            log.Debug("GetRate is run for " + currency + " " + date.ToString("dd/MM/yyyy"));
            var query = new NameValueCollection();

            query["start_period"] = date.ToString("yyyy-MM-dd", new CultureInfo("en-US"));
            query["end_period"]   = date.ToString("yyyy-MM-dd", new CultureInfo("en-US"));
            query["currency"]     = currency;

            var header = new NameValueCollection();

            header["api-key"] = Appconfig.BOTAPIKey;
            var callResult = await RESTServiceCall.GetJSONAsync(Appconfig.BOTServiceEndPoint, query, header);

            dynamic response = callResult;

            if (response.result.success == "true")
            {
                try
                {
                    var    data          = response.result.data["data_detail"].First;
                    string period        = data.period;
                    string currency_pair = (string)data.currency_id;
                    string buy           = data[Appconfig.BuyValue];
                    if (String.IsNullOrWhiteSpace(buy))
                    {
                        buy = "0";
                    }
                    string sell = data[Appconfig.SellValue];
                    if (String.IsNullOrWhiteSpace(sell))
                    {
                        sell = "0";
                    }
                    log.Debug("GetRate Extracting Data complete at " + period + " " + currency_pair + " " + buy + " " + sell);

                    bool isAPIComplete = !String.IsNullOrWhiteSpace(period);
                    if (!isAPIComplete)
                    {
                        var timestampDate = DateTime.ParseExact((string)response.result.timestamp, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US"));
                        var lastupdated   = DateTime.ParseExact((string)response.result.data.data_header.last_updated, "yyyy-MM-dd", new CultureInfo("en-US"));

                        //ถ้า date เป็นของวันก่อนหน้า ถือว่าา APIComplete
                        //หรือถ้า date เป็นของวันนี้ และ timestamp บอกว่าเลย 6 โมงเย็น จะถือว่า complete เช่นกัน
                        if (date.CompareTo(timestampDate.Date) < 0)
                        {
                            isAPIComplete = true;
                        }
                        else
                        {
                            if (timestampDate.Hour >= 18)
                            {
                                isAPIComplete = true;
                            }
                        }
                    }

                    return(new Result <CurrencyRate> {
                        Success = true, Data = new CurrencyRate {
                            Date = date, Buy = Convert.ToDecimal(buy), Sell = Convert.ToDecimal(sell), isAPIComplete = isAPIComplete, isSyncSAP = false, Currency = currency_pair
                        }
                    });
                }
                catch (Exception ex)
                {
                    log.Debug("GetRate REST calling pass but extracting data error" + ex.Message);
                    ExceptionHandling.LogException(ex);
                    return(new Result <CurrencyRate> {
                        Success = false, Failure = FailureType.UnexpectedServiceBehaviorError, Message = ex.Message
                    });
                }
            }
            else
            {
                string errorMsg = string.Empty;
                JToken errors   = response.result["error"] as JToken;
                foreach (dynamic error in errors)
                {
                    errorMsg += string.Format(@" {0}:{1} ", error.code, error.message);
                }
                log.Debug("GetRate REST calling ERROR Occured" + errorMsg);
                return(new Result <CurrencyRate> {
                    Success = false, Failure = FailureType.DatabaseConnectionError, Message = errorMsg
                });
            }
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            Appconfig.Initialize(path, ConfigurationManager.AppSettings, null);

            #region Logger
            log4net.GlobalContext.Properties["LOG4NET_ERROR"] = Appconfig.LOG4NET_ERROR; //log file path
            log4net.GlobalContext.Properties["LOG4NET_DEBUG"] = Appconfig.LOG4NET_DEBUG; //log file path
            log4net.Config.XmlConfigurator.Configure();
            #endregion
            var      currencyRatioDict = Appconfig.CurrencyRatioDict;
            DateTime programDatetime   = DateTime.Now;
            DateTime runningDate;
            if (programDatetime.Hour > Appconfig.BOTHourUpdate)
            {
                runningDate = new DateTime(programDatetime.Year, programDatetime.Month, programDatetime.Day);
            }
            else
            {
                var programDatetimeYesterday = programDatetime.AddDays(-1);
                runningDate = new DateTime(programDatetimeYesterday.Year, programDatetimeYesterday.Month, programDatetimeYesterday.Day);
            }
            if (args != null && args.Count() > 0)
            {
                DateTime tryResult;
                if (DateTime.TryParseExact(args.First(), "d/MM/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out tryResult))
                {
                    runningDate = tryResult;
                }
            }

            log.Debug("*******************************************************************");
            log.Debug("PROGRAM RUNS ON " + programDatetime.ToString("dd/MM/yyyy HH:mm:ss"));
            log.Debug("*******************************************************************");
            JsonLogService db        = new JsonLogService(Appconfig.JsonLog);
            var            dateToRun = new List <DateTime>();
            if (!Appconfig.RecoveryMode)
            {
                dateToRun.Add(runningDate);                                                       // we could check last date run is yesterday|| today ? if not we cound add lost day in between
                var lastDataDate = db.GetLastRunningDate();
                if (lastDataDate != default(DateTime) && lastDataDate.CompareTo(runningDate) < 0) // 0 means run second time for the day, 1 is not possible (if we do not force them to run future's day)
                {
                    log.Debug("-----------------------------------------------------------------");
                    log.Debug("CHECKING LAST RUNING DATE FOR SPECIFY DATES TO RUN (IF THERE IS MISSING RUNNING ON SOME DAYS)");
                    log.Debug("-----------------------------------------------------------------");
                    var timeSpanDiff = runningDate.Subtract(lastDataDate);
                    if (timeSpanDiff.TotalDays > 1)
                    {
                        int dayToRecover = Convert.ToInt32(timeSpanDiff.TotalDays) - 1;
                        for (int i = 1; i <= dayToRecover; i++)
                        {
                            dateToRun.Add(runningDate.AddDays(-i));
                        }
                    }
                }
            }
            else
            {
                foreach (var recoveryDate in Appconfig.RecoveryDate)
                {
                    DateTime tryResult;
                    if (DateTime.TryParseExact(recoveryDate, "d/M/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out tryResult))
                    {
                        dateToRun.Add(tryResult);
                    }
                }
            }

            foreach (var transactionDate in dateToRun)
            {
                #region  BOT API
                log.Debug("-----------------------------------------------------------------");
                log.Debug("API Call Start");
                log.Debug("-----------------------------------------------------------------");

                //var todayLog = db.GetDailyLog(transactionDate);//??
                List <Task> taskList = new List <Task>();
                foreach (var currencyPair in Appconfig.SyncCurrency)
                {
                    var currencyInDb = db.GetOrCreateCurrency(transactionDate, currencyPair);
                    //if sap is sync we will not call api again
                    if (currencyInDb.isSyncSAP == false)
                    {
                        if (currencyInDb.isAPIComplete)
                        {
                            log.Debug(String.Format(@"NOTE : THERE WAS FINISHED API CALL BUT SAP ERROR --> RECALL API AGAIN {0} {1}", currencyInDb.Currency, currencyInDb.Date.ToShortDateString()));
                        }
                        taskList.Add(APIExecute(currencyInDb, transactionDate));
                    }
                }

                var unfinishedAPI = db.GetUnfinishedBOTSync().Where(x => x.Date != transactionDate && Appconfig.SyncCurrency.Contains(x.Currency) && x.isSyncSAP == false);
                foreach (var currencyPair in unfinishedAPI)
                {
                    taskList.Add(APIExecute(currencyPair, currencyPair.Date));
                }
                Task.WhenAll(taskList).Wait();
                log.Debug("-----------------------------------------------------------------");
                log.Debug("API Call Successfully");
                log.Debug("-----------------------------------------------------------------");
                if (!db.SaveChange())
                {
                    log.Debug("-----------------------------------------------------------------");
                    log.Debug("Log Update Error");
                    log.Debug("-----------------------------------------------------------------");
                }
                else
                {
                    log.Debug("-----------------------------------------------------------------");
                    log.Debug("Log Update Successful");
                    log.Debug("-----------------------------------------------------------------");
                }

                #endregion
            }

            #region API Patch for non-value date
            log.Debug("==============================================================================");
            log.Debug("CHECK PATCHING START");
            log.Debug("==============================================================================");
            try
            {
                var patchingNeededDates = db.GetAllLog().Where(x => x.CurrenciesRate.Any(c => Appconfig.SyncCurrency.Contains(c.Currency) && c.isAPIComplete == true && c.isSyncSAP == false && c.Sell_SAP == (decimal)0 && c.Buy_SAP == (decimal)0)).ToList();//REVIEW
                if (patchingNeededDates.Count > 0)
                {
                    log.Debug("PATCHING FOUND");
                    Patching(Appconfig.SyncCurrency, patchingNeededDates);
                    log.Debug("PATCHING END");
                }
            }
            catch (Exception ex)
            {
                log.Debug("==============================================================================");
                log.Debug("CHECK PATCHING ERROR : CHECK THE EXCEPTION BELOW");
                log.Debug("==============================================================================");
                ExceptionHandling.LogException(ex);
            }

            #endregion

            #region SAP Part
            /// we will send sap only isAPIcomplete and if none of Buy and Sell we will use the last known value before that day to be value sent to SAP
            /// send only currency config, only isAPIComplete = true, only isSAPComplete = false
            log.Debug("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            log.Debug("SAP START");
            log.Debug("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            bool   isSAPCompleted = true;
            string SAPErrorMsg    = string.Empty;
            try
            {
                var sapSent = db.GetAllLog().Where(x => x.CurrenciesRate.Any(c => Appconfig.SyncCurrency.Contains(c.Currency) && c.isAPIComplete == true && c.isSyncSAP == false && c.Sell_SAP != (decimal)0 && c.Buy_SAP != (decimal)0)).ToList();
                #region  SAP Connection
                DestinationRegister.RegistrationDestination(new SAPDestinationSetting
                {
                    AppServerHost = Appconfig.SAPServerHost,
                    Client        = Appconfig.SAPClient,
                    User          = Appconfig.SAPUser,
                    Password      = Appconfig.SAPPassword,
                    SystemNumber  = Appconfig.SAPSystemNumber,
                    SystemID      = Appconfig.SAPSystemID,
                });
                var          des      = RfcDestinationManager.GetDestination(DestinationRegister.Destination());
                IRfcFunction function = des.Repository.CreateFunction("ZBAPI_EXCHANGERATE_UPDATE");
                #endregion

                #region example for input structure as input bapi

                /*
                 * TABLE :I_EXCHANGE
                 * STRUCTURE BAPI1093_0
                 *  RATE_TYPE	Exchange Rate Type , B = buy // M = sell
                 *  FROM_CURR	From currency
                 *  TO_CURRNCY	To-currency
                 *  VALID_FROM	Date from Which Entry Is Valid (yyyy-MM-dd)
                 *  EXCH_RATE	Direct Quoted Exchange Rate
                 *  FROM_FACTOR	Ratio for the "From" Currency Units, 1 // if JPY this is 100
                 *  TO_FACTOR	Ratio for the "To" Currency Units, 1
                 *  EXCH_RATE_V	Indirect Quoted Exchange Rate ****No input
                 *  FROM_FACTOR_V	Ratio for the "From" Currency Units ****No input
                 *  TO_FACTOR_V	Ratio for the "To" Currency Units ****No input
                 */
                IRfcTable           table   = function["I_EXCHANGE"].GetTable();//table
                List <CurrencyRate> sentSAP = new List <CurrencyRate>();
                foreach (var dailyLog in sapSent)
                {
                    foreach (var cur in dailyLog.CurrenciesRate.Where(c => Appconfig.SyncCurrency.Contains(c.Currency) && c.isAPIComplete == true && c.isSyncSAP == false && c.Sell_SAP != (decimal)0 && c.Buy_SAP != (decimal)0))
                    {
                        table.Append();                                  //create new row
                        IRfcStructure Buy            = table.CurrentRow; //current structure ,row
                        string        structure_name = Buy.Metadata.Name;
                        //Buy
                        Buy.SetValue("RATE_TYPE", "B");
                        Buy.SetValue("FROM_CURR", cur.Currency);
                        Buy.SetValue("TO_CURRNCY", "THB");
                        Buy.SetValue("VALID_FROM", dailyLog.Date.ToString("yyyy-MM-dd", new CultureInfo("en-US")));
                        Buy.SetValue("EXCH_RATE", cur.Buy_SAP.ToString("0.#####"));
                        if (currencyRatioDict.ContainsKey(cur.Currency))
                        {
                            Buy.SetValue("FROM_FACTOR", currencyRatioDict[cur.Currency]);
                        }
                        else
                        {
                            Buy.SetValue("FROM_FACTOR", 1);
                        }
                        Buy.SetValue("TO_FACTOR", 1);
                        log.Debug(String.Format("{0}  {1}  {2}  {3}  {4}", "B", cur.Currency, "THB", dailyLog.Date.ToString("ddMMyyyy", new CultureInfo("en-US")), cur.Buy_SAP.ToString("0.#####")));

                        table.Append();                        //create new row
                        IRfcStructure Sell = table.CurrentRow; //current structure ,row
                                                               //Sell
                        Sell.SetValue("RATE_TYPE", "M");
                        Sell.SetValue("FROM_CURR", cur.Currency);
                        Sell.SetValue("TO_CURRNCY", "THB");
                        Sell.SetValue("VALID_FROM", dailyLog.Date.ToString("yyyy-MM-dd", new CultureInfo("en-US")));
                        Sell.SetValue("EXCH_RATE", cur.Sell_SAP.ToString("0.#####"));
                        if (currencyRatioDict.ContainsKey(cur.Currency))
                        {
                            Sell.SetValue("FROM_FACTOR", currencyRatioDict[cur.Currency]);
                        }
                        else
                        {
                            Sell.SetValue("FROM_FACTOR", 1);
                        }
                        Sell.SetValue("TO_FACTOR", 1);
                        log.Debug(String.Format("{0}  {1}  {2}  {3}  {4}", "M", cur.Currency, "THB", dailyLog.Date.ToString("ddMMyyyy", new CultureInfo("en-US")), cur.Sell_SAP.ToString("0.#####")));
                        sentSAP.Add(cur);
                    }
                }

                var count = table.Count;
                #endregion
                if (count > 0)
                {
                    try
                    {
                        function.Invoke(des);
                        sentSAP.ForEach(x =>
                        {
                            x.isSyncSAP = true;
                        });
                    }
                    catch (SAP.Middleware.Connector.RfcAbapClassicException ex)
                    {
                        if (ex.Key == "SAPSQL_ARRAY_INSERT_DUPREC")
                        {
                            //dublicate record found
                            log.Debug("-----------------------------------------------------------------");
                            log.Debug("SAP BAPI CALL Error : DUBLICATED RECORD FOUND IN SAP.");
                            log.Debug("-----------------------------------------------------------------");
                        }
                        ExceptionHandling.LogException(ex);
                    }
                    catch (Exception ex)
                    {
                        isSAPCompleted = false;
                        SAPErrorMsg   += Environment.NewLine + ex.Message;
                        log.Debug("-----------------------------------------------------------------");
                        log.Debug("SAP BAPI CALL Error : READ THE EXCEPTION DETAIL.");
                        log.Debug("-----------------------------------------------------------------");
                        ExceptionHandling.LogException(ex);
                    }
                }
                //Call bapi

                #region example for fetch structure as object

                /*
                 *  IRfcParameter export = function["PRHEADER"];
                 * IRfcStructure structure = export.GetStructure();
                 * var setting = new PropertiesList<DataContainer>
                 * {
                 *  { "PREQ_NO", x=>x.PREQ_NO},
                 *  { "PREQ_NO", x=>x.PREQ_NO},
                 *  { "PR_TYPE", x=>x.PR_TYPE},
                 *  { "CTRL_IND", x=>x.CTRL_IND},
                 * };
                 * DataContainer output = structure.ToObject(setting);*/
                #endregion

                IRfcParameter returnTable = function["I_EXCHANGE"];
                IRfcTable     table1      = returnTable.GetTable();

                //foreach (IRfcStructure record in table1)
                //{
                //    Console.WriteLine(String.Format("{0}:{1}", record.GetInt("PREQ_ITEM"), record.GetValue("PREQ_ITEM").ToString()));
                //}

                if (!db.SaveChange())
                {
                    log.Debug("-----------------------------------------------------------------");
                    log.Debug("Log Update Error");
                    log.Debug("-----------------------------------------------------------------");
                }
                else
                {
                    log.Debug("-----------------------------------------------------------------");
                    log.Debug("Log Update Successful");
                    log.Debug("-----------------------------------------------------------------");
                }
            }
            catch (Exception ex)
            {
                isSAPCompleted = false;
                SAPErrorMsg   += Environment.NewLine + ex.Message;
                log.Debug("-----------------------------------------------------------------");
                log.Debug("SAP PART Error :  READ THE EXCEPTION DETAIL.");
                log.Debug("-----------------------------------------------------------------");
                ExceptionHandling.LogException(ex);
            }

            #endregion



            #region AlertMsg

            try
            {
                if (!Appconfig.RecoveryMode &&
                    db.GetOrCreateDailyLog(runningDate).CurrenciesRate.Any(x => Appconfig.SyncCurrency.Contains(x.Currency) && x.isSyncSAP == false && x.Sell != (decimal)0 && x.Buy != (decimal)0) &&
                    programDatetime.Date.AddDays(-1) == runningDate.Date &&
                    programDatetime.Hour < Appconfig.BOTHourUpdate && programDatetime.Hour > Appconfig.AlertCutOffTime)
                {
                    //recovery mode is off
                    //there is some sync currency which cannot sent to SAP found and it is not dayoff (sell && buy !=0)
                    //program is running on not today for sure (not after 18.00 of the day) (not before 7.00 of the program date)

                    MailService mailService = new MailService(Appconfig.MailServer, Appconfig.MailServerPort);

                    //send email to user
                    Email userMail = new Email();
                    userMail.Cc          = Appconfig.AlertAdminEmail;
                    userMail.From        = Appconfig.MailAdminAddress;
                    userMail.To          = Appconfig.AlertUserEmail;
                    userMail.Subject     = @"[BOTExchangeRate] ERROR UPDATE TO SAP NOTIFICATION";
                    userMail.SenderName  = @"BOTExchange Automatic Email Alert";
                    userMail.BodyMessage = MailTemplateUser(runningDate, Appconfig.SyncCurrency);

                    mailService.SendMail(userMail);
                    //send email to admin if exception found
                    if (!isSAPCompleted)
                    {
                        Email adminMail = new Email();
                        adminMail.From        = Appconfig.MailAdminAddress;
                        adminMail.To          = Appconfig.AlertAdminEmail;
                        adminMail.Subject     = @"[BOTExchangeRate] ERROR UPDATE TO SAP NOTIFICATION [DEBUG]";
                        adminMail.SenderName  = @"BOTExchange Automatic Email Alert";
                        adminMail.BodyMessage = MailTemplateAdmin(runningDate, Appconfig.SyncCurrency, SAPErrorMsg);
                        mailService.SendMail(adminMail);
                    }
                }
            }
            catch (Exception ex)
            {
                log.Debug("-----------------------------------------------------------------");
                log.Debug("EMAIL ALERT ERROR");
                log.Debug("-----------------------------------------------------------------");
                ExceptionHandling.LogException(ex);
            }

            #endregion


            log.Debug("*******************************************************************");
            log.Debug("PROGRAM RUNS COMPLETED " + programDatetime.ToString("dd/MM/yyyy HH:mm:ss"));
            log.Debug("*******************************************************************");
        }
Beispiel #3
0
        public static async Task <Result <List <DailyLog> > > GetRatePatching(string currency, DateTime dateStart, DateTime dateEnd)
        {
            log.Debug("GetRate Patching is run for " + currency + " " + dateStart.ToString("dd/MM/yyyy") + " to " + dateEnd.ToString("dd/MM/yyyy"));
            var query = new NameValueCollection();

            query["start_period"] = dateStart.ToString("yyyy-MM-dd", new CultureInfo("en-US"));
            query["end_period"]   = dateEnd.ToString("yyyy-MM-dd", new CultureInfo("en-US"));
            query["currency"]     = currency;

            var header = new NameValueCollection();

            header["api-key"] = Appconfig.BOTAPIKey;
            var callResult = await RESTServiceCall.GetJSONAsync(Appconfig.BOTServiceEndPoint, query, header);

            dynamic response = callResult;

            if (response.result.success == "true")
            {
                try
                {
                    var output = new List <DailyLog>();
                    foreach (var data in response.result.data["data_detail"])
                    {
                        string period        = data.period;
                        string currency_pair = (string)data.currency_id;
                        string buy           = data[Appconfig.BuyValue];
                        if (String.IsNullOrWhiteSpace(buy))
                        {
                            buy = "0";
                        }
                        string sell = data[Appconfig.SellValue];
                        if (String.IsNullOrWhiteSpace(sell))
                        {
                            sell = "0";
                        }
                        log.Debug("GetRatePatching Extracting Data complete at " + period + " " + currency_pair + " " + buy + " " + sell);
                        if (!String.IsNullOrWhiteSpace(period))
                        {
                            var      date = DateTime.ParseExact(period, "yyyy-MM-dd", new CultureInfo("en-US"));
                            DailyLog log  = new DailyLog()
                            {
                                CurrenciesRate = new List <CurrencyRate>
                                {
                                    new CurrencyRate {
                                        Date = date, Buy = Convert.ToDecimal(buy), Sell = Convert.ToDecimal(sell), isAPIComplete = true, isSyncSAP = false, Currency = currency_pair
                                    }
                                }
                                ,
                                Date = date
                            };
                            output.Add(log);
                        }
                    }
                    return(new Result <List <DailyLog> > {
                        Success = true, Data = output
                    });
                }
                catch (Exception ex)
                {
                    log.Debug("GetRate REST calling pass but extracting data error" + ex.Message);
                    ExceptionHandling.LogException(ex);
                    return(new Result <List <DailyLog> > {
                        Success = false, Failure = FailureType.UnexpectedServiceBehaviorError, Message = ex.Message
                    });
                }
            }
            else
            {
                string errorMsg = string.Empty;
                JToken errors   = response.result["error"] as JToken;
                foreach (dynamic error in errors)
                {
                    errorMsg += string.Format(@" {0}:{1} ", error.code, error.message);
                }
                log.Debug("GetRate REST calling ERROR Occured" + errorMsg);
                return(new Result <List <DailyLog> > {
                    Success = false, Failure = FailureType.DatabaseConnectionError, Message = errorMsg
                });
            }
        }