public FrayteResult DeleteCountryPublicHoliday(int countrypublcHolidayId)
        {
            FrayteResult result = new FrayteResult();

            try
            {
                var countryPublicHoliday = new CountryPublicHoliday {
                    CountryPublicHolidayId = countrypublcHolidayId
                };

                dbContext.CountryPublicHolidays.Attach(countryPublicHoliday);
                dbContext.CountryPublicHolidays.Remove(countryPublicHoliday);
                dbContext.SaveChanges();

                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.Errors = new List <string>();
                result.Errors.Add(ex.Message);
            }

            return(result);
        }
        public async Task <CountryPublicHolidayResponse> GetPublicHolidaysByYear(int year)
        {
            if (year < 0)
            {
                return(GetExceptionCountryPublicHolidayResponse("Invalid Year, Please pass correct parameters."));
            }
            using (HttpClient client = new HttpClient())
            {
                string[] countriesCodes = Helper.GetCountriesCodes();
                this.countryPublicHolidayResponse = new CountryPublicHolidayResponse();
                this.countryPublicHolidayResponse.CountryPublicHolidays = new List <CountryPublicHoliday>();
                CountryPublicHoliday currCountryPublicHoliday;

                foreach (string code in countriesCodes)
                {
                    var publicHolidaysResponse = await GetPublicHolidays(year, code);

                    currCountryPublicHoliday = new CountryPublicHoliday();
                    currCountryPublicHoliday.PublicHolidays = publicHolidaysResponse.PublicHolidays;
                    currCountryPublicHoliday.CountryName    = Helper.GetCountryByCode(code);
                    currCountryPublicHoliday.CountryCode    = code;
                    this.countryPublicHolidayResponse.CountryPublicHolidays.Add(currCountryPublicHoliday);
                }

                this.countryPublicHolidayResponse.Status = true;
                return(this.countryPublicHolidayResponse);
            }
        }
        private AnswerResponse FormatThirdQuestionAnswerResponse(CountryPublicHoliday result)
        {
            AnswerResponse formattedResponse = new AnswerResponse();

            formattedResponse.AdditionalInfo = new List <string>();
            formattedResponse.QuestionString = ThirdQuestionString;
            formattedResponse.Answer         = result.CountryCode + ", " + result.CountryName;
            foreach (var holiday in result.UniqueHolidays)
            {
                formattedResponse.AdditionalInfo.Add(string.Format("{0} is unique holiday for {1}", holiday.Date.ToShortDateString(), holiday.Name));
            }
            formattedResponse.Explanation = string.Format("The country contains {0} unique holidays in 2019!", result.UniqueHolidays.Count);
            return(formattedResponse);
        }
        public AnswerResponse AnswerQuestion(int questionNumber)
        {
            if (questionNumber == 1)
            {
                CountryPublicHoliday result = this.publicHolidaysOperations.GetMaxHolidaysCountry(2019);
                if (result != null)
                {
                    this.answerResponse = FormatFirstQuestionAnswerResponse(result);
                }
                else
                {
                    return(GetExceptionAnswerResponse(ExceptionMessageString));
                }
            }

            else if (questionNumber == 2)
            {
                HolidaysMonth result = this.publicHolidaysOperations.GetMaxHolidaysMonthGlobally(2019);
                if (result != null)
                {
                    this.answerResponse = FormatSecondQuestionAnswerResponse(result);
                }
                else
                {
                    return(GetExceptionAnswerResponse(ExceptionMessageString));
                }
            }

            else if (questionNumber == 3)
            {
                CountryPublicHoliday result = this.publicHolidaysOperations.GetMaxUniqueHolidaysCountry(2019);
                if (result != null)
                {
                    this.answerResponse = FormatThirdQuestionAnswerResponse(result);
                }
                else
                {
                    return(GetExceptionAnswerResponse(ExceptionMessageString));
                }
            }

            else
            {
                return(GetExceptionAnswerResponse("Question number is not provided, Please pass correct question number."));
            }

            this.answerResponse.Status = true;
            return(this.answerResponse);
        }
        public CountryPublicHoliday GetMaxHolidaysCountry(int year)
        {
            var allHolidays = this._publicHolidaysService.GetPublicHolidaysByYear(year);

            if (allHolidays != null && allHolidays.Result != null && allHolidays.Result.Status == true)
            {
                CountryPublicHoliday result = new CountryPublicHoliday();
                int maxHolidays             = 0;
                foreach (var country in allHolidays.Result.CountryPublicHolidays)
                {
                    if (country.PublicHolidays.Count > maxHolidays)
                    {
                        result      = country;
                        maxHolidays = country.PublicHolidays.Count;
                    }
                }

                return(result);
            }
            else
            {
                return(null);
            }
        }
        public CountryPublicHoliday GetMaxUniqueHolidaysCountry(int year)
        {
            // In order to get unique holidays, I will create a Dictionary of dates, and for each date will add countries that had this date as holiday
            // after that, the result will be exist in this list
            // Dictionary is better choice that list, as looking for item in Dictionary is O(1) time complexity, and in list O(n). so Dictionary will save more running time

            var allHolidays = this._publicHolidaysService.GetPublicHolidaysByYear(year);

            if (allHolidays != null && allHolidays.Result != null && allHolidays.Result.Status == true)
            {
                CountryPublicHoliday result = new CountryPublicHoliday();
                Dictionary <DateTime, List <PublicHoliday> > holidayDates   = new Dictionary <DateTime, List <PublicHoliday> >();
                Dictionary <string, List <PublicHoliday> >   countriesCount = new Dictionary <string, List <PublicHoliday> >(); // key: country name, value: all unique holidays
                int maxUnique = 0;

                foreach (CountryPublicHoliday country in allHolidays.Result.CountryPublicHolidays)
                {
                    foreach (PublicHoliday holiday in country.PublicHolidays)
                    {
                        if (!holidayDates.ContainsKey(holiday.Date))
                        {
                            holidayDates[holiday.Date] = new List <PublicHoliday>();
                            holidayDates[holiday.Date].Add(holiday);
                        }
                        else
                        {
                            holidayDates[holiday.Date].Add(holiday);
                        }
                    }
                }

                foreach (var date in holidayDates)
                {
                    if (date.Value.Count == 1)
                    {
                        if (!countriesCount.ContainsKey(date.Value[0].CountryCode))
                        {
                            countriesCount[date.Value[0].CountryCode] = new List <PublicHoliday>();
                            countriesCount[date.Value[0].CountryCode].Add(date.Value[0]);
                        }
                        else
                        {
                            countriesCount[date.Value[0].CountryCode].Add(date.Value[0]);
                        }
                    }
                }

                foreach (var country in countriesCount)
                {
                    if (country.Value.Count > maxUnique)
                    {
                        maxUnique             = country.Value.Count;
                        result.CountryName    = Helper.GetCountryByCode(country.Key);
                        result.CountryCode    = country.Key;
                        result.UniqueHolidays = country.Value;
                    }
                }

                return(result);
            }
            else
            {
                return(null);
            }
        }
        public FrayteCountry SaveCountry(FrayteCountry frayteCountry)
        {
            Country saveCountry;

            if (frayteCountry.CountryId > 0)
            {
                saveCountry = dbContext.Countries.Where(p => p.CountryId == frayteCountry.CountryId).FirstOrDefault();

                saveCountry.CountryName = frayteCountry.Name;
                saveCountry.CountryCode = frayteCountry.Code;
            }
            else
            {
                saveCountry = new Country();

                saveCountry.CountryName = frayteCountry.Name;
                saveCountry.CountryCode = frayteCountry.Code;

                dbContext.Countries.Add(saveCountry);
            }

            dbContext.SaveChanges();
            frayteCountry.CountryId = saveCountry.CountryId;

            //After saving the country information, we need to save its document information
            if (frayteCountry.CountryDocuments != null && frayteCountry.CountryDocuments.Count > 0)
            {
                foreach (CountryDocument document in frayteCountry.CountryDocuments)
                {
                    CountryDocument saveDocument;
                    if (document.CountryDocumentId > 0)
                    {
                        saveDocument = dbContext.CountryDocuments.Where(p => p.CountryDocumentId == document.CountryDocumentId).FirstOrDefault();

                        saveDocument.DocumentName = document.DocumentName;
                        saveDocument.ShipmentType = document.ShipmentType;
                    }
                    else
                    {
                        saveDocument = new CountryDocument();

                        saveDocument.CountryId    = frayteCountry.CountryId;
                        saveDocument.DocumentName = document.DocumentName;
                        saveDocument.ShipmentType = document.ShipmentType;

                        dbContext.CountryDocuments.Add(saveDocument);
                    }

                    dbContext.SaveChanges();
                    document.CountryDocumentId = saveDocument.CountryDocumentId;
                }
            }

            if (frayteCountry.CountryPublicHolidays != null && frayteCountry.CountryPublicHolidays.Count > 0)
            {
                foreach (var document in frayteCountry.CountryPublicHolidays)
                {
                    CountryPublicHoliday countrypublicholiday;
                    if (document.CountryPublicHolidayId > 0)
                    {
                        countrypublicholiday = dbContext.CountryPublicHolidays.Where(p => p.CountryPublicHolidayId == document.CountryPublicHolidayId).FirstOrDefault();

                        countrypublicholiday.CountryId         = frayteCountry.CountryId;
                        countrypublicholiday.Description       = document.Description;
                        countrypublicholiday.PublicHolidayDate = document.PublicHolidayDate;
                    }
                    else
                    {
                        countrypublicholiday = new CountryPublicHoliday();

                        countrypublicholiday.CountryId         = frayteCountry.CountryId;
                        countrypublicholiday.Description       = document.Description;
                        countrypublicholiday.PublicHolidayDate = document.PublicHolidayDate;

                        dbContext.CountryPublicHolidays.Add(countrypublicholiday);
                    }

                    dbContext.SaveChanges();
                    document.CountryPublicHolidayId = countrypublicholiday.CountryPublicHolidayId;
                }
            }

            return(frayteCountry);
        }