private void BusinessFileCleaner()
        {
            try
            {
                var leaseTime    = Convert.ToInt32(_configuration["LeaseTime:BusinessFile"]);
                var businessFile = _entity.BusinessFile;
                var schedules    = _entity.BusinessFile.Select(jt => jt.JobTimeline.Schedule).Distinct().ToList();

                foreach (var schedule in schedules)
                {
                    var jobtimeline = _entity.JobTimeline.Where(s => s.ScheduleId == schedule.Id).OrderByDescending(s => s.StartTime).FirstOrDefault();
                    if (jobtimeline.JobStatusId == (int)JobStatus.Done && (DateTime.UtcNow - jobtimeline.StartTime).TotalDays > leaseTime)
                    {
                        _entity.BusinessFile.RemoveRange(businessFile.Where(j => j.JobTimeline.ScheduleId == jobtimeline.ScheduleId));
                    }
                }

                _entity.SaveChanges();
            }
            catch (Exception ex)
            {
                _logger.Information($"JobService.BusinessFileCleaner()");
                _logger.Error(ex.Message);
            }
        }
Exemple #2
0
        public bool SaveSymbolsForExchange(AvailableExchanges name)
        {
            try
            {
                IBaseExchangeClient exchangeClient = _exchangesData.GetClientInstance(name);
                var symbols = exchangeClient.GetSymbols().ToList();
                List <MarketModel> markets = FindAndPopulateDistinctMarketsForExchange(symbols);

                #region For Testing
                ////test if all symbols are distributed to different markets
                //var totalSimbolCount = symbols.Count;
                //var simbolCountInMarkets = 0;
                //foreach (var market in markets)
                //{
                //    simbolCountInMarkets += market.CurrencyPairs.Count;
                //}
                //if (simbolCountInMarkets == totalSimbolCount)
                //{
                //    //success
                //    totalSimbolCount = 0;
                //}
                #endregion

                var exchange = _context.Exchange.FirstOrDefault(e => e.Name == name.ToString());
                if (exchange.Market.Any())
                {
                    return(false);
                }
                foreach (var market in markets)
                {
                    var marketToSave = new Market
                    {
                        Exchange = exchange,
                        Name     = market.Name,
                        StatusId = (int)Statuses.Active,
                    };
                    _context.Market.Add(marketToSave);

                    foreach (var pair in market.Pairs)
                    {
                        var symbolToSave = new Symbol
                        {
                            Market   = marketToSave,
                            Name     = pair,
                            StatusId = (int)Statuses.Active
                        };
                        _context.Symbol.Add(symbolToSave);
                    }
                }
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                _logger.Information($"ExchangesService.SaveSymbolsForExchange(name: {name})");
                _logger.Error(ex.Message);
                return(false);
            }
            return(true);
        }
        public IResponse <NoValue> AddBlocksWithTransactions(long jobId, List <EthereumBlockModel> blocks)
        {
            var response = new Response <NoValue>();

            try
            {
                var stopwatch = Stopwatch.StartNew();

                foreach (var block in blocks)
                {
                    Block blockDb = new Block
                    {
                        BlockNumber   = block.BlockNumber,
                        JobTimelineId = jobId,
                        BlockTime     = block.TimeStamp,
                        CreatedAt     = DateTime.UtcNow
                    };

                    _entity.Block.Add(blockDb);

                    var transactions = new List <BlockTransaction>();

                    foreach (var transaction in block.BlockTransactions)
                    {
                        transactions.Add(new BlockTransaction
                        {
                            Block  = blockDb,
                            TxHash = transaction.Hash
                        });
                    }

                    _entity.BlockTransaction.AddRange(transactions);
                }

                _entity.SaveChanges();

                stopwatch.Stop();
                _logger.Information($"BlockTransactionService.AddBlocksWithTransactions(jobId: {jobId}). Time elapsed: {stopwatch.Elapsed.TotalSeconds} seconds.");

                response.Status = Common.Enums.StatusEnum.Success;
            }
            catch (Exception ex)
            {
                _logger.Information($"BlockTransactionService.AddBlocksWithTransactions(jobId: {jobId})");
                _logger.Error(ex.Message);
                response.Status  = Common.Enums.StatusEnum.Error;
                response.Message = ex.Message;
            }

            return(response);
        }
        public async Task <IResponse <NoValue> > AddToTransaction(TransactionDataModel model)
        {
            var response = new Response <NoValue>();

            var transactions = new List <Transaction>();

            try
            {
                var jobTimeline = _entity.JobTimeline.Find(model.JobId);

                var fromAdapter = jobTimeline.Schedule.JobDefinition.Adapter;
                var toAdapter   = jobTimeline.Schedule.JobDefinition.Adapter1;

                var transactionList = model.Data;

                //remove intersecting transactions if job is recurrent
                var newTransactionsResponse = RemoveIntersection(model.Data, jobTimeline);

                if (newTransactionsResponse.Value.Count > 0)
                {
                    foreach (var transaction in newTransactionsResponse.Value)
                    {
                        var transactionTypeResponse = GetTransactionType(transaction);
                        var accountsResponse        = await _accountService.GetAccount(transaction.TransactionAccount, fromAdapter.EnterpriseAdapter.FirstOrDefault().Id, toAdapter.CryptoAdapter.FirstOrDefault().Id);

                        transactions.Add(new Transaction
                        {
                            TransactionId       = transaction.TransactionId,
                            AccountId           = accountsResponse.Value.Id,
                            TransactionAmount   = Math.Abs(Convert.ToDecimal(transaction.TransactionAmount)),
                            CreatedAt           = DateTime.UtcNow,
                            UpdatedAt           = DateTime.UtcNow,
                            TransactionTypeId   = transactionTypeResponse.Value.Id,
                            TransactionStatusId = (int)Common.Enums.TransactionStatus.Pending,
                            JobTimelineId       = model.JobId,
                        });
                    }
                    _entity.Transaction.AddRange(transactions);
                    _entity.SaveChanges();
                }
                response.Status = Common.Enums.StatusEnum.Success;
            }
            catch (Exception ex)
            {
                response.Message = Message.SomethingWentWrong;
                response.Status  = Common.Enums.StatusEnum.Error;
                _logger.Information($"TransactionService.AddToTransaction(model: {model})");
                _logger.Error(ex.Message);
            }
            return(response);
        }
Exemple #5
0
 public void DeleteUserProfile(long Id)
 {
     try
     {
         var user = _entity.UserProfile.Find(Id);
         _entity.UserProfile.Remove(user);
         _entity.SaveChanges();
     }
     catch (Exception ex)
     {
         _logger.Information($"UserProfileService.DeleteUserProfile(Id: {Id}");
         _logger.Error(ex.Message);
     }
 }
Exemple #6
0
        public IResponse <NoValue> CreateJobDefinition(JobDefinitionModel model)
        {
            var result = new Response <NoValue>();

            try
            {
                var jobDefinition = new Dal.JobDefinition
                {
                    Name          = model.Name,
                    Retry         = model.Retry,
                    NumberOfRetry = (model.Retry) ? model.NumberOfRetry : default(int),
                    From          = model.From,
                    To            = model.To,
                    UserProfileId = model.UserProfileId,
                };

                _entity.JobDefinition.Add(jobDefinition);

                var propertiesDal   = new List <Dal.JobDefinitionProperty>();
                var propertiesModel = model.PropertiesGet ?? new List <PropertyModel>();

                foreach (var property in propertiesModel)
                {
                    propertiesDal.Add(
                        new Dal.JobDefinitionProperty
                    {
                        JobDefinitionId = jobDefinition.Id,
                        PropertyId      = _entity.Property.FirstOrDefault(p => p.Name == property.Name).Id,
                        Value           = property.Value ?? String.Empty
                    });
                }

                _entity.JobDefinitionProperty.AddRange(propertiesDal);
                _entity.SaveChanges();

                result.Message = "Job definition added successfully.";
                result.Status  = StatusEnum.Success;
            }
            catch (Exception ex)
            {
                result.Status  = StatusEnum.Error;
                result.Message = Message.SomethingWentWrong;
                _logger.Information($"JobDefinitionService.CreateJobDefinition(model: {model})");
                _logger.Error(ex.Message);
            }

            return(result);
        }
Exemple #7
0
        public async Task <IResponse <Account> > GetAccount(string transactionAccount, long enterpriseAdapterId, long cryptoAdapterId)
        {
            var response = new Response <Account>();

            try
            {
                var accountModel = _entity.Account.Where(t => t.TransactionAccount == transactionAccount && t.EnterpriseAdapterId == enterpriseAdapterId && t.CryptoAdapterId == cryptoAdapterId).FirstOrDefault();

                if (accountModel == null)
                {
                    var blockchainAccountResponse = await _blockchainService.NewAccount(cryptoAdapterId);

                    if (blockchainAccountResponse.Status == StatusEnum.Success)
                    {
                        var account = new Account
                        {
                            TransactionAccount  = transactionAccount,
                            EnterpriseAdapterId = enterpriseAdapterId,
                            CryptoAdapterId     = cryptoAdapterId,
                            CreditAddress       = blockchainAccountResponse.Value.CreditAddress,
                            DebitAddress        = blockchainAccountResponse.Value.DebitAddress
                        };

                        response.Value  = account;
                        response.Status = StatusEnum.Success;

                        _entity.Account.Add(account);
                        _entity.SaveChanges();
                    }
                    else
                    {
                        //logger
                    }
                }
                else
                {
                    response.Value = accountModel;
                }
            }
            catch (Exception ex)
            {
                _logger.Information($"AccountService.GetAccount(transactionAccount: {transactionAccount}, enterpriseAdapterId: {enterpriseAdapterId}, cryptoAdapterId: {cryptoAdapterId})");
                _logger.Error(ex.Message);
                response.Status = StatusEnum.Error;
            }

            return(response);
        }
Exemple #8
0
        public IResponse <NoValue> WriteNumberOfTransactions(long jobId, int numberOfTransactions)
        {
            var response = new Response <NoValue>();

            try
            {
                var jobTimeline = _entity.JobTimeline.Find(jobId);
                jobTimeline.NumberOfTransactions = jobTimeline.NumberOfTransactions != null ? jobTimeline.NumberOfTransactions + numberOfTransactions : numberOfTransactions;
                _entity.SaveChanges();
            }
            catch (Exception ex)
            {
                _logger.Information($"JobTimelineService.WriteNumberOfTransactions(jobId: {jobId}, numberOfTransactions: {numberOfTransactions})");
                _logger.Error(ex.Message);
            }

            return(response);
        }
        public IResponse <NoValue> CreateBusinessAdapter(BusinessAdapterModel businessAdapter, long userProfileId)
        {
            var response = new Response <NoValue>();

            try
            {
                //refactor with properties
                Adapter newAdapter = new Adapter
                {
                    Name              = businessAdapter.Name,
                    UserProfileId     = userProfileId,
                    AdapterTypeItemId = (int)businessAdapter.BusinessAdapterType,
                    StatusId          = (int)Statuses.Active,
                    DirectionId       = (int)businessAdapter.Direction
                };

                BusinessAdapter newBusinessAdapter = new BusinessAdapter
                {
                    AdapterId = newAdapter.Id,
                    Filename  = businessAdapter.FileName
                };

                _entity.Adapter.Add(newAdapter);
                _entity.BusinessAdapter.Add(newBusinessAdapter);

                _entity.SaveChanges();

                response.Message = "Business adapter added successfully.";
                response.Status  = StatusEnum.Success;
            }
            catch (Exception ex)
            {
                _logger.Information($"BusinessAdapterService.CreateBusinessAdapter(userProfileId: {userProfileId}");
                _logger.Error(ex.Message);
                response.Status  = StatusEnum.Error;
                response.Message = ex.Message;
            }

            return(response);
        }
        public void AdapterSeed(long userProfileId)
        {
            try
            {
                foreach (var node in _seed.Value.CryptoAdapters ?? new List <Cryptoadapter>().ToArray())
                {
                    var adapter = _mapper.Map <Adapter>(node);
                    adapter.UserProfileId = userProfileId;
                    _entity.Adapter.Add(adapter);

                    var cryptoAdapter = _mapper.Map <CryptoAdapter>(node);
                    cryptoAdapter.Adapter = adapter;
                    _entity.CryptoAdapter.Add(cryptoAdapter);

                    foreach (var property in node.Properties ?? new List <Model.Property>().ToArray())
                    {
                        var cryptoAdapterProperty = _mapper.Map <CryptoAdapterProperty>(property);
                        cryptoAdapterProperty.CryptoAdapter = cryptoAdapter;
                        _entity.CryptoAdapterProperty.Add(cryptoAdapterProperty);
                    }
                }

                foreach (var business in _seed.Value.BusinessAdapters ?? new List <Businessadapter>().ToArray())
                {
                    var adapter = _mapper.Map <Adapter>(business);
                    adapter.UserProfileId = userProfileId;
                    _entity.Adapter.Add(adapter);

                    var businessAdapter = _mapper.Map <BusinessAdapter>(business);
                    businessAdapter.Adapter = adapter;
                    _entity.BusinessAdapter.Add(businessAdapter);
                }

                _entity.SaveChanges();
            }
            catch (Exception ex)
            {
                _logger.Information($"AdapterService.AdapterSeed(userProfileId: {userProfileId})");
                _logger.Error(ex.Message);
            }
        }
        public List <NotificationModel> GetNotifications(long userProfileId)
        {
            var notificationListModel = new List <NotificationModel>();

            foreach (var item in _entity.Notification.Where(u => u.UserProfileId == userProfileId))
            {
                var notification = new NotificationModel
                {
                    CreatedAt = item.CreatedAt,
                    Message   = item.Message,
                    UpdatedAt = item.UpdatedAt,
                    StatusId  = item.StatusId,
                    UserId    = item.UserProfileId
                };

                notificationListModel.Add(notification);
                item.StatusId  = (int)Statuses.Notified;
                item.UpdatedAt = DateTime.Now;
            }

            _entity.SaveChanges();

            return(notificationListModel.OrderByDescending(ca => ca.CreatedAt).Take(10).ToList());
        }
Exemple #12
0
        public async Task <IResponse <NoValue> > CreateCryptoAdapter(CryptoAdapterModel model, long userProfileId)
        {
            var result = new Response <NoValue>();

            try
            {
                var connection = await TestConnection(model);

                if (connection.Status != StatusEnum.Success)
                {
                    result.Status  = StatusEnum.Error;
                    result.Message = connection.Message;
                    return(result);
                }

                Adapter newAdapter = new Adapter
                {
                    Name = model.Name,
                    AdapterTypeItemId = (int)model.NodeType,
                    DirectionId       = (int)model.Direction,
                    UserProfileId     = userProfileId,
                    StatusId          = (int)Statuses.Active
                };
                _entity.Adapter.Add(newAdapter);

                CryptoAdapter cryptoAdapter = new CryptoAdapter
                {
                    RpcAddr   = model.RpcAddr,
                    RpcPort   = model.RpcPort.ToString(),
                    AdapterId = newAdapter.Id
                };
                _entity.CryptoAdapter.Add(cryptoAdapter);

                switch (model.Direction)
                {
                case DirectionEnum.Source:
                    foreach (var prop in model.Properties.First().SourceProperties ?? new List <PropertyModel>())
                    {
                        var cryptoAdapterProperty = new CryptoAdapterProperty
                        {
                            CryptoAdapter = cryptoAdapter,
                            PropertyId    = prop.Id,
                            Value         = prop.Value ?? String.Empty
                        };
                        _entity.CryptoAdapterProperty.Add(cryptoAdapterProperty);
                    }
                    break;

                case DirectionEnum.Destination:
                    foreach (var prop in model.Properties.First().DestinationProperties ?? new List <PropertyModel>())
                    {
                        var cryptoAdapterProperty = new CryptoAdapterProperty
                        {
                            CryptoAdapter = cryptoAdapter,
                            PropertyId    = prop.Id,
                            Value         = prop.Value ?? String.Empty
                        };
                        _entity.CryptoAdapterProperty.Add(cryptoAdapterProperty);
                    }
                    break;

                default:
                    break;
                }
                _entity.SaveChanges();

                result.Status  = StatusEnum.Success;
                result.Message = "Connection test succeeded. Crypto adapter added successfully.";
            }
            catch (Exception ex)
            {
                result.Status  = StatusEnum.Error;
                result.Message = Message.SomethingWentWrong;
                _logger.Information($"CryptoAdapterService.CreateCryptoAdapter(model: {model}, userProfileId: {userProfileId})");
                _logger.Error(ex.Message);
            }

            return(result);
        }
Exemple #13
0
        public IResponse <NoValue> ChangeJobStatus(Common.Enums.JobStatus jobStatus, long Id, int transactionCount = default(int), int blockCount = default(int), bool limitExceeded = default(bool))
        {
            var response = new Response <NoValue>();

            try
            {
                var jobTimeline       = _entity.JobTimeline.Where(jt => jt.Id == Id).FirstOrDefault();
                var adapterTypeFromId = jobTimeline.Schedule.JobDefinition.Adapter.AdapterTypeItem.AdapterTypeId;
                var adapterTypeToId   = jobTimeline.Schedule.JobDefinition.Adapter1.AdapterTypeItem.AdapterTypeId;
                var user   = _user.UserManager.Users.Where(u => u.UserProfileId == jobTimeline.Schedule.UserProfileId).FirstOrDefault();
                var userId = _user.UserManager.GetUserIdAsync(user).Result;

                string message = String.Empty;
                if (jobStatus == Common.Enums.JobStatus.Executing)
                {
                    _entity.Notification.Add(new Notification
                    {
                        CreatedAt     = DateTime.Now,
                        StatusId      = (int)Statuses.Unnotified,
                        UserProfileId = jobTimeline.Schedule.UserProfileId,
                        UserId        = userId,
                        Message       = "Job execution started"
                    });
                    jobTimeline.JobStatusId = (int)jobStatus;
                    message = "Your job is being executed";
                }
                else if (jobStatus == Common.Enums.JobStatus.Done)
                {
                    jobTimeline.JobStatusId = (int)jobStatus;

                    _entity.Notification.Add(new Notification
                    {
                        CreatedAt     = DateTime.Now,
                        StatusId      = (int)Statuses.Unnotified,
                        UserProfileId = jobTimeline.Schedule.UserProfileId,
                        UserId        = userId,
                        Message       = "Your job is done"
                    });

                    if (adapterTypeFromId != (int)Common.Enums.AdapterType.Crypto)
                    {
                        message = $"Your job is done; {transactionCount} transaction(s) transferred";
                    }
                    else if (adapterTypeToId == (int)Common.Enums.AdapterType.Business)
                    {
                        message = $"Your job is done; {blockCount} block(s) found with total of {transactionCount} transaction(s)";
                    }
                    else
                    {
                        message = $"Your job is done; {blockCount} block(s) transferred with total of {transactionCount} transaction(s)";
                    }
                }
                else if (jobStatus == Common.Enums.JobStatus.Failed)
                {
                    _entity.Notification.Add(new Notification
                    {
                        CreatedAt     = DateTime.Now,
                        StatusId      = (int)Statuses.Unnotified,
                        UserProfileId = jobTimeline.Schedule.UserProfileId,
                        UserId        = userId,
                        Message       = "Your job failed"
                    });

                    if (limitExceeded == true)
                    {
                        jobStatus = Common.Enums.JobStatus.Done;
                        jobTimeline.JobStatusId = (int)jobStatus;
                        message = "Block limit exceeded. Your job failed.";
                    }
                    else
                    {
                        jobStatus = Common.Enums.JobStatus.Done;
                        jobTimeline.JobStatusId = (int)jobStatus;
                        message = "Something went wrong. Your job failed.";
                    }
                }

                jobTimeline.JobHistory.Add(new JobHistory
                {
                    JobTimelineId = jobTimeline.Id,
                    UpdatedAt     = DateTime.UtcNow,
                    JobStatusId   = (int)jobStatus,
                    Message       = message
                });

                _entity.SaveChanges();
                response.Status = StatusEnum.Success;
            }
            catch (Exception ex)
            {
                response.Status  = StatusEnum.Error;
                response.Message = ex.Message;
                _logger.Information($"JobHistoryService.ChangeJobStatus(jobStatus: {jobStatus}, Id: {Id}, transactionCount: {transactionCount})");
                _logger.Error(ex.Message);
            }
            return(response);
        }
        public IResponse <NoValue> Create(EnterpriseAdapterModel model, long userProfileID)
        {
            var result = new Response <NoValue>();

            try
            {
                #region connectivity
                var connection = TestConnection(model);
                if (connection.Status != StatusEnum.Success)
                {
                    result.Status  = StatusEnum.Error;
                    result.Message = connection.Message;
                    return(result);
                }
                #endregion

                var enterpriseAdapter = new EnterpriseAdapter();
                var newAdapter        = new Adapter
                {
                    Name = model.Name,
                    AdapterTypeItemId = (int)model.EnterpriseAdapter,
                    UserProfileId     = userProfileID,
                    StatusId          = (int)Statuses.Active,
                    DirectionId       = (int)model.Direction
                };
                _entity.Adapter.Add(newAdapter);

                enterpriseAdapter.ServerIP     = model.ServerIP;
                enterpriseAdapter.Port         = (int)model.Port;
                enterpriseAdapter.Username     = model.Username;
                enterpriseAdapter.Password     = model.Password;
                enterpriseAdapter.DatabaseName = model.DatabaseName;
                enterpriseAdapter.AdapterId    = newAdapter.Id;
                _entity.EnterpriseAdapter.Add(enterpriseAdapter);

                switch (model.Direction)
                {
                case DirectionEnum.Destination:
                    foreach (var prop in model.Properties.First().DestinationProperties ?? new List <PropertyModel>())
                    {
                        var enterpriseAdapterProperty = new EnterpriseAdapterProperty
                        {
                            EnterpriseAdapter = enterpriseAdapter,
                            PropertyId        = prop.Id,
                            Value             = prop.Value ?? String.Empty
                        };
                        _entity.EnterpriseAdapterProperty.Add(enterpriseAdapterProperty);
                    }
                    break;


                case DirectionEnum.Source:
                    if ((int)model.EnterpriseAdapter < 4)
                    {
                        var adapterTable = new EnterpriseAdapterTable
                        {
                            TableName           = model.ParentTable,
                            EnterpriseAdapterId = enterpriseAdapter.Id
                        };
                        _entity.EnterpriseAdapterTable.Add(adapterTable);

                        var y = _entity.EnterpriseAdapterTableColumn.Select(x => x.Id).ToList().LastOrDefault();
                        if (model.Columns != null)
                        {
                            for (int i = 0; i < model.Columns.Count; i++)
                            {
                                var child = new EnterpriseAdapterTableColumn
                                {
                                    Id                       = (int)model.Columns[i].Id,
                                    ParentId                 = model.Columns[i].ParentId,
                                    IsForeignKey             = model.Columns[i].IsForeignKey,
                                    IsPrimaryKey             = model.Columns[i].IsPrimaryKey,
                                    PropertyNameId           = (int?)model.Columns[i].PropertyNameId,
                                    RelatedTableName         = model.Columns[i].RelatedTableName,
                                    DataTypeId               = 1,
                                    ColumnName               = model.Columns[i].ColumnName,
                                    EnterpriseAdapterTableId = adapterTable.Id
                                };
                                if (model.Columns[i].PropertyNameId == 0)
                                {
                                    child.PropertyNameId = null;
                                }

                                if (model.Columns[i].ParentId == 0)
                                {
                                    child.ParentId = null;
                                }
                                else
                                {
                                    child.ParentId = model.Columns[i].ParentId;
                                }
                                _entity.EnterpriseAdapterTableColumn.Add(child);
                            }
                        }
                    }
                    foreach (var prop in model.Properties.First().SourceProperties ?? new List <PropertyModel>())
                    {
                        var enterpriseAdapterProperty = new EnterpriseAdapterProperty
                        {
                            EnterpriseAdapter = enterpriseAdapter,
                            PropertyId        = prop.Id,
                            Value             = prop.Value ?? String.Empty
                        };
                        _entity.EnterpriseAdapterProperty.Add(enterpriseAdapterProperty);
                    }
                    break;

                default:
                    break;
                }

                _entity.SaveChanges();
                result.Status  = StatusEnum.Success;
                result.Message = "Connection test succeeded. Enterprise adapter added successfully.";
            }

            catch (Exception ex)
            {
                result.Status  = StatusEnum.Error;
                result.Message = Message.SomethingWentWrong;
                _logger.Information($"EnterpriseAdapterService.Create(model: {model}, userProfileID: {userProfileID})");
                _logger.Error(ex.Message);
            }
            return(result);
        }
        public IResponse <NoValue> CreateSchedule(ScheduleModel model, IEnumerable <DateTime> dates)
        {
            var result = new Response <NoValue>();
            var jobs   = new List <JobTimeline>();

            try
            {
                int counter = 0;

                if (model.StartDate < DateTime.Now)
                {
                    result.Status  = Common.Enums.StatusEnum.Error;
                    result.Message = "Jobs cannot be created in the past";
                    return(result);
                }

                var schedule = new Schedule
                {
                    Title           = model.Title,
                    StartDate       = model.StartDate.ToUniversalTime(),
                    EndDate         = model.EndDate,
                    UserProfileId   = model.UserProfileId,
                    JobDefinitionId = model.JobDefinitionId,
                    RecurrenceRule  = model.RecurrenceRule,
                    CreatedAt       = DateTime.UtcNow,
                    Description     = model.Description
                };

                _entity.Schedule.Add(schedule);

                if (dates != null)
                {
                    var jobexecutiondates = dates.Select(d => new JobTimeline
                    {
                        ScheduleId  = schedule.Id,
                        JobStatusId = (int)Common.Enums.JobStatus.Pending,
                        StartTime   = d.ToUniversalTime()
                    }).ToList();

                    jobs = jobexecutiondates;
                    _entity.JobTimeline.AddRange(jobexecutiondates);

                    counter = jobexecutiondates.Count;

                    foreach (var jobExecutionDate in jobexecutiondates)
                    {
                        jobExecutionDate.JobHistory.Add(new JobHistory
                        {
                            JobTimelineId = jobExecutionDate.Id,
                            UpdatedAt     = DateTime.UtcNow,
                            JobStatusId   = (int)Common.Enums.JobStatus.Pending,
                            Message       = "Your job is waiting for execution"
                        });
                    }
                }
                else
                {
                    var jobTimeline = _entity.JobTimeline.Add(new JobTimeline
                    {
                        ScheduleId  = schedule.Id,
                        JobStatusId = (int)Common.Enums.JobStatus.Pending,
                        StartTime   = schedule.StartDate.ToUniversalTime()
                    });

                    _entity.JobHistory.Add(new JobHistory
                    {
                        JobTimelineId = jobTimeline.Id,
                        UpdatedAt     = DateTime.UtcNow,
                        JobStatusId   = (int)Common.Enums.JobStatus.Pending,
                        Message       = "Your job is waiting for execution"
                    });
                    jobs.Add(jobTimeline);
                    counter = 1;
                }

                _entity.SaveChanges();
                result.Message = $"{counter} job(s) scheduled successfully.";
                result.Status  = Common.Enums.StatusEnum.Success;

                //sync jobs with Hangfire (needs to be refactored)
                foreach (var job in jobs)
                {
                    var idHangfire = BackgroundJob.Schedule(() => _jobService.ExecuteJob(job.Id), job.StartTime);
                    job.HangfireId = idHangfire;
                }

                _entity.SaveChanges();
            }
            catch (Exception ex)
            {
                result.Status  = Common.Enums.StatusEnum.Error;
                result.Message = Message.SomethingWentWrong;
                _logger.Information($"ScheduleService.CreateSchedule(model: {model}, dates: {dates})");
                _logger.Error(ex.Message);
            }

            return(result);
        }