protected void btnBulkSendToNAV_Click(object sender, EventArgs e)
        {
            try
            {
                var config = SPContext.Current.GetNavWebServiceConnection();
                if (config.IsEmpty())
                {
                    throw new Exception("NAV connection info has not been specified!");
                }

                if (!IsCurrentUserAManagerForWorker())
                {
                    throw new Exception("Only Manager can Send timesheets to NAV for current user!");
                }

                // get timesheets to Send to NAV
                var approvedRosters = this.GetTimesheetsByStatus(10); // 10 = 'Approved'
                if (!approvedRosters.Any())
                {
                    throw new Exception("There is nothing to send to NAV");
                }

                // get mapping
                var _mappingSettings = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize <List <Roster.Presentation.Layouts.MapElem> >(config.Mapping);

                var calendarPeriod = Utils.GetCalendarViewPeriod(SPContext.Current.Web.GetDateOptions(Request), "week");
                var listDbFields   = new RosterConfigService().GetList(TableIDs.TIMESHEET_ROSTERS).ListMetadataFields.Select(fld => fld.GetDbField());

                // init Servicea
                CreateTimeSheetLines_Service srv = new CreateTimeSheetLines_Service();
                srv.Url         = config.CreateTimesheetUrl;
                srv.Credentials = new NetworkCredential(config.User, config.Password);
                ProcessTimeSheets procSrv = new ProcessTimeSheets();
                procSrv.Url         = config.ProcessTimesheetsUrl;
                procSrv.Credentials = new NetworkCredential(config.User, config.Password);

                Dictionary <Guid, string> errors = new Dictionary <Guid, string>();
                List <Guid> successIDs           = new List <Guid>();
                foreach (var roster in approvedRosters)
                {
                    string batchNo = Guid.NewGuid().ToString("N").Substring(0, 20);
                    try
                    {
                        var newLine = new CreateTimeSheetLines();
                        // generic values
                        newLine.Key = "0";
                        newLine.External_Time_Sheet_No            = batchNo;
                        newLine.Time_Sheet_Starting_Date          = calendarPeriod.Item1.Date;
                        newLine.Time_Sheet_Starting_DateSpecified = true;
                        // fill Line from timesheet roster
                        newLine.FillFromRoster(roster, listDbFields, _mappingSettings);

                        // create entry in NAV temp table
                        srv.Create(ref newLine);
                        // process timesheet entry
                        procSrv.ProcessTimeSheet(batchNo, false);

                        successIDs.Add(roster.Id);
                    }
                    catch (Exception ex)
                    {
                        errors.Add(roster.Id, ex.Message);
                    }
                }

                // init StoredProcedure params
                var paramCollection = new List <Tuple <string, object> >();
                paramCollection.Add(new Tuple <string, object>("@id", String.Join(",", successIDs)));
                paramCollection.Add(new Tuple <string, object>("@reason", string.Format("Bulk submit to NAV at {0}", DateTime.Now.ToString())));
                paramCollection.Add(new Tuple <string, object>("@message", ""));
                // set new STATUS
                string message = new RosterDataService().ExecuteProcedure("[dbo].[SubmitedToNAV]", paramCollection);

                if (errors.Any())
                {
                    throw new Exception(String.Join("<br/>", errors.Select(er => string.Format("Error submitting roster '{0}': {1}", er.Key, er.Value))));
                }

                txtNotification.Value = "Success";
            }
            catch (Exception ex)
            {
                txtErrorMsg.Value = ex.Message;
            }
        }