Search code examples
c#quartz-schedulerchoetl

Calling method with quartz scheduler to create ACH file using ChoNacha gives exception


I want to generate ACH files automatically with the help of scheduler. Scheduler call gives me exception whereas direct call from URL does not I have implemented the following code for creating ACH files

    //scheduler job
    Task IJob.Execute(IJobExecutionContext context)
    {
        SchedularMethodsController obj = new SchedularMethodsController();
        var T = Task.Run(() => obj.AchFileGenerator(DateTime.Now));\
        T.Wait();
        return T;
    }

the method to generate and write the ACH file is as follow :-

public void AchFileGenerator(DateTime Dt)
        {
            ChoNACHAConfiguration config = new ChoNACHAConfiguration();
            config.DestinationBankRoutingNumber = "999999999";
            config.OriginatingCompanyId = "7999999999";
            config.DestinationBankName = ("PNC Bank").ToUpper();
            config.OriginatingCompanyName = ("automatecondominium").ToUpper();
            config.ReferenceCode = ("mgmt").ToUpper();
            config.BlockingFactor = 10;
            var unitowners = Achbll.GetUnitOwnerPaymentList(Dt).ToList();
            var FileName = "ACH_" + ((DateTime.Now.ToString()).Replace(" ", "_").Replace(":", "_")) + ".txt";
            var backpath = "CondoDocuments\\DocumentLibrary\\" + FileName;
            var path = HttpRuntime.AppDomainAppPath + backpath;

            using (var fs = System.IO.File.Create(path))
            {
                fs.Close();
                fs.Dispose();
            }

            try
            {
                using (var nachaWriter = new ChoNACHAWriter(path, config))
                { 

                    using (var bw2 = nachaWriter.CreateBatch(200, "PPD", "DIR DEBIT", DateTime.Now, DateTime.Now.AddDays(1), null, null, '1', null, null))
                    {
                        foreach (var owner in unitowners)
                        {
                            if (!string.IsNullOrEmpty(owner.AccountNo) && !string.IsNullOrEmpty(owner.BankRoutingCode))
                            {

                                var UA = Cipher.decrypt(owner.AccountNo);
                                var BR = Cipher.decrypt(owner.BankRoutingCode);
                                var Name = owner.UnitOwnerName.Split(' ');
                                if (Name.Length > 1)
                                {
                                    using (var entry = bw2.CreateDebitEntryDetail(27, BR.ToString(), UA.ToString(), 779, " 18H00A " + owner.UnitNo.ToString(), (Name[1] + ", " + Name[0]).ToUpper().ToString()))
                                    {
                                        //entry.CheckDigit = '0';

                                    }
                                }
                                else
                                {
                                    using (var entry = bw2.CreateDebitEntryDetail(27, BR.ToString(), UA.ToString(), 779, " 18H00B " + owner.UnitNo.ToString(), (Name[0]).ToUpper().ToString()))
                                    {
                                        //entry.CheckDigit = '0';

                                    }
                                }

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }

        }

This is my scheduler call in global.asax:-

   protected void Application_Start()
        {
            Invoker ob = new Invoker();
            ob.StartScheduling();

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

        }

Job invoke class:-

 public async void StartScheduling()
        {
            // construct a scheduler factory
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };

            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail job = JobBuilder.Create<ExecutableJobs>()
                            .WithIdentity("myJob", "group1") // name "myJob", group "group1"
                            .Build();

            var start = DateTime.Now.AddMinutes(1);
            ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity("trigger3", "group1")
                        //.StartAt(start) // if a start time is not given (if this line were omitted), "now" is implied
                        .WithSimpleSchedule(x => x
                            .WithIntervalInMinutes(1).
                            RepeatForever())
                        .ForJob(job)
                        .Build();

            await scheduler.ScheduleJob(job, trigger);
        }

The exception i getting is :-

1) Exception Information ********************************************* Exception Type: System.TypeInitializationException TypeName: ChoETL.ChoAppSettings Message: The type initializer for 'ChoETL.ChoAppSettings' threw an exception. Data: System.Collections.ListDictionaryInternal TargetSite: System.String GetValue(System.String, System.String, Boolean) HelpLink: NULL Source: ChoETL HResult: -2146233036

StackTrace Information ********************************************* at ChoETL.ChoAppSettings.GetValue(String key, String defaultValue, Boolean saveDefaultValue) at ChoETL.ChoETLFramework.GetConfigValue(String key, String defaultValue) at ChoETL.ChoETLFramework.GetConfigValue[T](String key, T defaultValue) at ChoETL.ChoETLFramework._Initialize()

2) Exception Information ********************************************* Exception Type: System.ArgumentException Message: exePath must be specified when not running inside a stand alone exe. ParamName: NULL Data: System.Collections.ListDictionaryInternal TargetSite: System.Configuration.Configuration OpenExeConfigurationImpl(System.Configuration.ConfigurationFileMap, Boolean, System.Configuration.ConfigurationUserLevel, System.String, Boolean) HelpLink: NULL Source: System.Configuration HResult: -2147024809

StackTrace Information ********************************************* at System.Configuration.ConfigurationManager.OpenExeConfigurationImpl(ConfigurationFileMap fileMap, Boolean isMachine, ConfigurationUserLevel userLevel, String exePath, Boolean preLoad) at System.Configuration.ConfigurationManager.OpenExeConfiguration(String exePath) at ChoETL.ChoAppSettings..cctor()



Solution

  • Seems to be bug in the ChoETL library. Will fix and release on the next version.

    In the mean time, please do as below to overcome this issue

    public void AchFileGenerator(DateTime Dt)
    {
        //Set this flag to fix the issue
        ChoETLFrxBootstrap.IsSandboxEnvironment = true;
    
    
        ChoNACHAConfiguration config = new ChoNACHAConfiguration();
        config.DestinationBankRoutingNumber = "999999999";
        config.OriginatingCompanyId = "7999999999";
    
    .....
    
    }
    

    UPDATE:

    Please install latest ChoETL (v1.0.8.4) nuget package.

    Let me know.