static void Main(string[] args) { string samlSite = "https://www.uat.com/"; OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); ClientContext ctx = am.GetADFSUserNameMixedAuthenticatedContext(samlSite, "username", "password", "domain", "adfs url", "adfs identifier"); var oList = ctx.Web.Lists.GetByTitle("BusinessBytes"); CamlQuery camlQuery = new CamlQuery(); camlQuery.ViewXml = "<View><RowLimit>10</RowLimit></View>"; ListItemCollection collListItem = oList.GetItems(camlQuery); ctx.Load(collListItem, items => items.Include( item => item.Id, item => item["BusinessByteTitle"], item => item.HasUniqueRoleAssignments)); ctx.ExecuteQuery(); foreach (var item in collListItem) { Console.WriteLine("{0} - {1}", item.Id, item["BusinessByteTitle"]); } }
static void Main(string[] args) { var mode = GetMode(args); try { //check to ensure there's at least one argument if (mode == Mode.invalid || args.Length > 2) { DisplayUsage(); return; } if (mode == Mode.debug) { //if we're in debug, to to the project directory and read the Branding files and settings.xml from there var dir = System.IO.Directory.GetCurrentDirectory(); dir = dir.Substring(0, dir.IndexOf("\\bin")); System.IO.Directory.SetCurrentDirectory(dir); } //code used to get the application to work for SP ADFS var siteUrl = String.Concat(GetConfigurationValue("url").TrimEnd(_TrimChars), "/", GetConfigurationValue("site").TrimEnd(_TrimChars)); if (args.Length > 1 && args[1].Equals("online", StringComparison.OrdinalIgnoreCase)) { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); using (ClientContext clientContext = am.GetADFSUserNameMixedAuthenticatedContext(siteUrl, GetConfigurationValue("username"), GetConfigurationValue("password"), GetConfigurationValue("domain"), GetConfigurationValue("adfsserver"), GetConfigurationValue("adfsurn"))) { Execute(siteUrl, clientContext, mode); } } else { using (ClientContext clientContext = new ClientContext(siteUrl)) { clientContext.Credentials = new NetworkCredential(GetConfigurationValue("username"), GetConfigurationValue("password"), GetConfigurationValue("domain")); Execute(siteUrl, clientContext, mode); } } Console.WriteLine("Done!"); } catch (Exception ex) { Console.WriteLine("Critical Error: {0}", ex.Message); } if (mode != Mode.debug) { Console.ReadLine(); } else { Console.WriteLine("Closing in 2 seconds..."); System.Threading.Thread.Sleep(2000); } }
public static void Session(SPDeployOptions options, Action <ClientContext> Code) { sp_deploy_settings.EchoCurrentParams(options); if (!String.IsNullOrEmpty(options.ADFSUrl)) { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); using (var clientContext = am.GetADFSUserNameMixedAuthenticatedContext(options.url, options.login, options.password, options.domain, options.ADFSUrl, options.relyingParty, 600)) { //var StartedDate = DateTime.Now; clientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs) { foreach (Cookie Cookie in webRequestEventArgs.WebRequestExecutor.WebRequest.CookieContainer.GetCookies(new Uri(options.url))) { if (Cookie.Name == "FedAuth") { var Expires = Cookie.Expires; var CurrentTime = DateTime.Now; var DateDiff = (Expires - CurrentTime).TotalMinutes; if (DateDiff < 3) { am.RefreshADFSUserNameMixedAuthenticatedContext(options.url, options.login, options.password, options.domain, options.ADFSUrl, options.relyingParty); } } } }; Code(clientContext); } } else { //using (var clientContext = new ClientContext(options.url)) //{ var clientContext = new ClientContext(options.url); if (options.Credentials != null) { clientContext.Credentials = options.Credentials; } if ((!String.IsNullOrEmpty(options.ClientId)) && (!String.IsNullOrEmpty(options.ClientSecret))) { TokenHelper.ClientId = options.ClientId; TokenHelper.ClientSecret = options.ClientSecret; var targetWeb = new Uri(options.url); string targetRealm = TokenHelper.GetRealmFromTargetUrl(targetWeb); var responseToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, targetWeb.Authority, targetRealm); clientContext = TokenHelper.GetClientContextWithAccessToken(targetWeb.ToString(), responseToken.AccessToken); } Code(clientContext); clientContext.Dispose(); //} } }
static void Main(string[] args) { try { var runStartTime = DateTime.Now; Console.WriteLine($"Run started {runStartTime}."); string groupPrefix = ""; string chargesLstNm = "Charges"; var authScheme = AuthScheme.ntlm; string adfsServer = null; string relyingParty = null; string userName = null; string domain = null; string pwd = null; var missingSecurityGroups = new HashSet <string>(); DateTime?billingCycleStart = null; var options = new OptionSet() { { "p|prefix_of_group=", v => groupPrefix = v } , { "c|cycle_start_date=", v => billingCycleStart = DateTime.ParseExact(v, "yyyy-MM-dd", CultureInfo.InvariantCulture) } , { "h|charges_list_name=", v => chargesLstNm = v } , { "s|auth_scheme=", v => authScheme = (AuthScheme)Enum.Parse(typeof(AuthScheme), v) } , { "S|adfs_server=", v => adfsServer = v } , { "P|relying_party=", v => relyingParty = v } , { "u|username="******"D|domain=", v => domain = v } , { "w|password="******"Argument -c|--cycle_start_date is mandatory."); System.Environment.Exit(1); } ServicePointManager.ServerCertificateValidationCallback = MyCertHandler; ClientContext cc = null; switch (authScheme) { case AuthScheme.ntlm: { if (userName != null && pwd != null && domain != null) { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); cc = am.GetNetworkCredentialAuthenticatedContext(extraArgs[0], userName, pwd, domain); } else { cc = new ClientContext(extraArgs[0]); cc.Credentials = System.Net.CredentialCache.DefaultCredentials; } break; } case AuthScheme.adfs: { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); cc = am.GetADFSUserNameMixedAuthenticatedContext(extraArgs[0], userName, pwd, domain, adfsServer, relyingParty); break; } } var query = new CamlQuery(); // populate or update charge from consumption string viewXml = null; viewXml = $@" <View><Query> <Where> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{((DateTime)billingCycleStart).ToString("yyyy-MM-dd")}</Value> </Eq> </Where> </Query></View>"; query.ViewXml = viewXml; cc.Load(cc.Web.RoleDefinitions); var gc = cc.Web.SiteGroups; cc.Load(gc); var readRD = cc.Web.RoleDefinitions.GetByName("Read"); cc.ExecuteQuery(); RoleDefinition restReadRD; try { restReadRD = cc.Web.RoleDefinitions.GetByName("Restricted Read"); cc.ExecuteQuery(); } catch { restReadRD = null; } var chargesLst = cc.Web.Lists.GetByTitle(chargesLstNm); var chargesLIC = chargesLst.GetItems(query); cc.Load(chargesLIC, items => items.Include( item => item["Account"] , item => item["HasUniqueRoleAssignments"] )); cc.ExecuteQuery(); foreach (var chargeLI in chargesLIC) { if (chargeLI.HasUniqueRoleAssignments) { chargeLI.ResetRoleInheritance(); cc.ExecuteQuery(); } chargeLI.BreakRoleInheritance(true, false); bool match = false; foreach (var g in gc) { if (g.LoginName == (groupPrefix + chargeLI["Account"].ToString())) { var rdb = new RoleDefinitionBindingCollection(cc); rdb.Add(restReadRD != null ? restReadRD : readRD); chargeLI.RoleAssignments.Add(g, rdb); match = true; break; } } if (!match) { missingSecurityGroups.Add(chargeLI["Account"].ToString()); } cc.ExecuteQuery(); } if (missingSecurityGroups.Count > 0) { Console.WriteLine($"Following accounts miss corresponding sharepoint groups"); foreach (String acct in missingSecurityGroups) { Console.WriteLine($"{acct}"); } } var runEndTime = DateTime.Now; Console.WriteLine($"Run ended {runEndTime}, lasting {(runEndTime - runStartTime).TotalMinutes.ToString("0.00")} minutes."); } catch (Exception ex) { Console.WriteLine($"{ex}"); throw; } }
static void Main(string[] args) { if (!EventLog.SourceExists(evtLogSrc)) { EventLog.CreateEventSource(evtLogSrc, "Application"); } try { var runStartTime = DateTime.Now; EventLog.WriteEntry(evtLogSrc, $"Run started {runStartTime}.", EventLogEntryType.Information); string groupPrefix = ""; int cycleOffset = -1; string accountsLstNm = "Accounts"; string ratesLstNm = "Rates"; string fixedConsumptionsLstNm = "Fixed Consumptions"; string consumptionsLstNm = "Consumptions"; string chargesLstNm = "Charges"; string billingPeriodStr = "1m"; bool isCycleOpen = false; bool? incremental = null; var authScheme = AuthScheme.ntlm; string adfsServer = null; string relyingParty = null; string userName = null; string domain = null; string pwd = null; bool deleteEndedFixedConsumptions = false; string lastRunFileName = "billease_last_run.log"; DateTime cycleCalibrationDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1, 0, 0, 0, DateTimeKind.Local); Dictionary <string, List <KeyValuePair <string, string> > > listColumnsToCopy = new Dictionary <string, List <KeyValuePair <string, string> > >(); listColumnsToCopy.Add("Account", new List <KeyValuePair <string, string> >()); listColumnsToCopy.Add("Rate", new List <KeyValuePair <string, string> >()); listColumnsToCopy.Add("Consumption", new List <KeyValuePair <string, string> >()); var options = new OptionSet() { { "p|prefix_of_group=", v => groupPrefix = v } , { "o|offset_of_cycle=", v => cycleOffset = int.Parse(v) } , { "b|billing_period=", v => billingPeriodStr = v } , { "d|cycle_calibration_date=", v => cycleCalibrationDate = DateTime.ParseExact(v, "yyyy-MM-dd", CultureInfo.InvariantCulture) } , { "a|accounts_list_name=", v => accountsLstNm = v } , { "r|rates_list_name=", v => ratesLstNm = v } , { "f|fixed_consumptions_list_name=", v => fixedConsumptionsLstNm = v } , { "c|consumptions_list_name=", v => consumptionsLstNm = v } , { "h|charges_list_name=", v => chargesLstNm = v } , { "A|account_columns_to_copy=", v => { var src = v; var dst = v; if (v.Contains(":")) { src = v.Substring(0, v.IndexOf(":")); dst = v.Substring(v.IndexOf(":") + 1); } listColumnsToCopy["Account"].Add(new KeyValuePair <string, string>(src, dst)); } } , { "R|rate_columns_to_copy=", v => { var src = v; var dst = v; if (v.Contains(":")) { src = v.Substring(0, v.IndexOf(":")); dst = v.Substring(v.IndexOf(":") + 1); } listColumnsToCopy["Rate"].Add(new KeyValuePair <string, string>(src, dst)); } } , { "C|consumption_columns_to_copy=", v => { var src = v; var dst = v; if (v.Contains(":")) { src = v.Substring(0, v.IndexOf(":")); dst = v.Substring(v.IndexOf(":") + 1); } listColumnsToCopy["Consumption"].Add(new KeyValuePair <string, string>(src, dst)); } } , { "O|is_cycle_open=", v => isCycleOpen = Convert.ToBoolean(v) } , { "i|incremental=", v => incremental = Convert.ToBoolean(v) } , { "l|last_run_log_file_name=", v => lastRunFileName = v } , { "s|auth_scheme=", v => authScheme = (AuthScheme)Enum.Parse(typeof(AuthScheme), v) } , { "S|adfs_server=", v => adfsServer = v } , { "P|relying_party=", v => relyingParty = v } , { "u|username="******"D|domain=", v => domain = v } , { "w|password="******"x|delete_ended_fixed_consumptions=", v => deleteEndedFixedConsumptions = Convert.ToBoolean(v) } }; List <String> extraArgs = options.Parse(args); if (incremental == null) { incremental = isCycleOpen; } ServicePointManager.ServerCertificateValidationCallback = MyCertHandler; ClientContext cc = null; switch (authScheme) { case AuthScheme.ntlm: { if (userName != null && pwd != null && domain != null) { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); cc = am.GetNetworkCredentialAuthenticatedContext(extraArgs[0], userName, pwd, domain); } else { cc = new ClientContext(extraArgs[0]); cc.Credentials = System.Net.CredentialCache.DefaultCredentials; } break; } case AuthScheme.adfs: { OfficeDevPnP.Core.AuthenticationManager am = new OfficeDevPnP.Core.AuthenticationManager(); cc = am.GetADFSUserNameMixedAuthenticatedContext(extraArgs[0], userName, pwd, domain, adfsServer, relyingParty); break; } } Match billingPeriodMatch = Regex.Match(billingPeriodStr, @"(\d)([mdy])"); int billingPeriod = 0; string billingPeriodUOM = null; if (billingPeriodMatch.Success) { billingPeriod = Int32.Parse(billingPeriodMatch.Groups[1].Value); billingPeriodUOM = billingPeriodMatch.Groups[2].Value; } var billingCycleStart = DateTime.Now; TimeSpan s = billingCycleStart - cycleCalibrationDate; switch (billingPeriodUOM) { case "d": billingCycleStart = cycleCalibrationDate.AddDays(s.TotalDays - (s.TotalDays % billingPeriod) + cycleOffset * billingPeriod); break; case "m": int monthDiff = (billingCycleStart.Year - cycleCalibrationDate.Year) * 12 + billingCycleStart.Month - cycleCalibrationDate.Month; billingCycleStart = cycleCalibrationDate.AddMonths(monthDiff - (monthDiff % billingPeriod) + cycleOffset * billingPeriod); break; case "y": int yearDiff = (int)s.TotalDays / 365; billingCycleStart = cycleCalibrationDate.AddYears(yearDiff - (yearDiff % billingPeriod) + cycleOffset * billingPeriod); break; } DateTime nextBillingcycleStart = DateTime.Now; switch (billingPeriodUOM) { case "d": nextBillingcycleStart = billingCycleStart.AddDays(billingPeriod); break; case "m": nextBillingcycleStart = billingCycleStart.AddMonths(billingPeriod); break; case "y": nextBillingcycleStart = billingCycleStart.AddYears(billingPeriod); break; } TimeRange billingRange = new TimeRange(billingCycleStart, nextBillingcycleStart); // get last run timestamp var lastRunTs = new DateTime(1970, 01, 01); try { string[] lines = System.IO.File.ReadAllLines(lastRunFileName); DateTime lastRunCycle = DateTime.Parse(lines[0]); if (lastRunCycle.Date == billingCycleStart.Date) { lastRunTs = DateTime.Parse(lines[1]); } } catch { } var query = new CamlQuery(); // deleted ended fixed consumptions if cycle is closed try { if (deleteEndedFixedConsumptions && !isCycleOpen) { query.ViewXml = $@"<View><Query> <Where> <Lt> <FieldRef Name='Service_x0020_End' /> <Value Type=”DateTime”>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Lt> </Where> </Query></View>"; var fixedConsumptionLst = cc.Web.Lists.GetByTitle(fixedConsumptionsLstNm); var fixedConsumptionDeletionLIC = fixedConsumptionLst.GetItems(query); cc.Load(fixedConsumptionDeletionLIC); cc.ExecuteQuery(); while (fixedConsumptionDeletionLIC.Count > 0) { ListItem fixedConsumptionLI = null; try { fixedConsumptionLI = fixedConsumptionDeletionLIC[0]; fixedConsumptionLI.DeleteObject(); cc.ExecuteQuery(); } catch (Exception ex) { EventLog.WriteEntry(evtLogSrc, $@"Error delete ended fixed consumption with id {fixedConsumptionLI["ID"]}. {ex}" , EventLogEntryType.Error); } } } } catch (Exception ex) { EventLog.WriteEntry(evtLogSrc, $@"Error delete ended fixed consumptions. {ex}", EventLogEntryType.Error); } // delete consumptions associated with // deleted or ended fixed consumptions query.ViewXml = $@" <View><Query> <Where> <And> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Eq> <Or> <Or> <Geq> <FieldRef Name='Fixed_x0020_Consumption_x0020_Re0' /> <Value Type=”DateTime”>{nextBillingcycleStart.ToString("yyyy-MM-dd")}</Value> </Geq> <Lt> <FieldRef Name='Fixed_x0020_Consumption_x0020_Re1' /> <Value Type=”DateTime”>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Lt> </Or> <And> <IsNull> <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' /> </IsNull> <Geq> <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' LookupId='TRUE' /> <Value Type=”Lookup”>0</Value> </Geq> </And> </Or> </And> </Where> </Query></View>"; var consumptionLst = cc.Web.Lists.GetByTitle(consumptionsLstNm); var consumptionFC = consumptionLst.Fields; var consumptionDeletionLIC = consumptionLst.GetItems(query); cc.Load(consumptionFC); cc.Load(consumptionDeletionLIC); cc.ExecuteQuery(); while (consumptionDeletionLIC.Count > 0) { var consumptionLI = consumptionDeletionLIC[0]; consumptionLI.DeleteObject(); cc.ExecuteQuery(); } // delete charges associated with deleted consumptions query = new CamlQuery(); query.ViewXml = $@"<View><Query> <Where> <And> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Eq> <And> <IsNull> <FieldRef Name='Consumption_x0020_Ref' /> </IsNull> <Geq> <FieldRef Name='Consumption_x0020_Ref' LookupId='TRUE' /> <Value Type=”Lookup”>0</Value> </Geq> </And> </And> </Where> </Query></View>"; var chgLst = cc.Web.Lists.GetByTitle(chargesLstNm); var chargesDeletionLIC = chgLst.GetItems(query); cc.Load(chargesDeletionLIC); cc.ExecuteQuery(); while (chargesDeletionLIC.Count > 0) { var chargeLI = chargesDeletionLIC[0]; chargeLI.DeleteObject(); cc.ExecuteQuery(); } // populate or update consumptions from fixed consumptions query = new CamlQuery(); query.ViewXml = $@" <View><Query> <Where> <And> <Or> <IsNull> <FieldRef Name='Service_x0020_Start' /> </IsNull> <Lt> <FieldRef Name='Service_x0020_Start' /> <Value Type='DateTime'>{nextBillingcycleStart.ToString("yyyy-MM-dd")}</Value> </Lt> </Or> <Or> <IsNull> <FieldRef Name='Service_x0020_End' /> </IsNull> <Gt> <FieldRef Name='Service_x0020_End' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Gt> </Or> </And> </Where> </Query></View>"; var fixedConsumptionsLst = cc.Web.Lists.GetByTitle(fixedConsumptionsLstNm); var fixedConsumptionLIC = fixedConsumptionsLst.GetItems(query); FieldCollection fixedConsumptionFC = fixedConsumptionsLst.Fields; cc.Load(fixedConsumptionFC); cc.Load(fixedConsumptionLIC); try { cc.ExecuteQuery(); foreach (var fixedConsumptionLI in fixedConsumptionLIC) { try { // check if consumption exists for the current billing cycle var consumptionItemQuery = new CamlQuery(); consumptionItemQuery.ViewXml = $@" <View><Query> <Where> <And> <Eq> <FieldRef Name='Fixed_x0020_Consumption_x0020_Re' LookupId='TRUE' /> <Value Type='Lookup'>{fixedConsumptionLI["ID"]}</Value> </Eq> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Eq> </And> </Where> </Query></View>"; var _consumptionLIC = consumptionLst.GetItems(consumptionItemQuery); cc.Load(_consumptionLIC); cc.ExecuteQuery(); ListItem consumptionItem; if (_consumptionLIC.Count > 0) { if (((DateTime)fixedConsumptionLI["Modified"]) < ((DateTime)_consumptionLIC[0]["Modified"])) { continue; } consumptionItem = _consumptionLIC[0]; } else { ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation(); consumptionItem = consumptionLst.AddItem(itemCreateInfo); } foreach (Field field in fixedConsumptionFC) { if (field.FromBaseType && field.InternalName != "Title") { continue; } if (consumptionFC.FirstOrDefault(f => (!f.FromBaseType || f.InternalName == "Title") && f.InternalName == field.InternalName ) == null) { continue; } consumptionItem[field.InternalName] = fixedConsumptionLI[field.InternalName]; } // calculate proration try { if (fixedConsumptionLI["Prorated"] != null && fixedConsumptionLI["Prorated"].ToString().Contains("Yes") ) { DateTime serviceStart = DateTime.MinValue; DateTime serviceEnd = DateTime.MaxValue; if (fixedConsumptionLI["Service_x0020_Start"] != null) { serviceStart = ((DateTime)fixedConsumptionLI["Service_x0020_Start"]).ToLocalTime(); } if (fixedConsumptionLI["Service_x0020_End"] != null) { serviceEnd = ((DateTime)fixedConsumptionLI["Service_x0020_End"]).ToLocalTime(); } TimeRange serviceRange = new TimeRange(serviceStart, serviceEnd); ITimeRange overlap = serviceRange.GetIntersection(billingRange); double portion = overlap.Duration.TotalDays / billingRange.Duration.TotalDays; if (fixedConsumptionLI["Quantity"] != null) { var proratedQty = ((double)fixedConsumptionLI["Quantity"]) * portion; if (fixedConsumptionLI["Prorated"].ToString() != "Yes") { proratedQty = Convert.ToInt32(proratedQty); } consumptionItem["Quantity"] = proratedQty; } if (fixedConsumptionLI["Amount"] != null) { consumptionItem["Amount"] = ((double)fixedConsumptionLI["Amount"]) * portion; } } } catch { EventLog.WriteEntry(evtLogSrc, $@"Error calculating proration for fixed consumption with ID={fixedConsumptionLI["ID"]}", EventLogEntryType.Error); } consumptionItem["Cycle"] = billingCycleStart; FieldLookupValue lookup = new FieldLookupValue(); lookup.LookupId = (int)fixedConsumptionLI["ID"]; consumptionItem["Fixed_x0020_Consumption_x0020_Re"] = lookup; consumptionItem.Update(); cc.ExecuteQuery(); } catch (Exception ex) { EventLog.WriteEntry(evtLogSrc, $@"Error creating consumption from fixed consumption with ID {fixedConsumptionLI["ID"]}. {ex}", EventLogEntryType.Error); } } } catch (Exception ex) { EventLog.WriteEntry(evtLogSrc, $@"Error creating consumption from fixed consumption. {ex}", EventLogEntryType.Error); } // set incremental to false if there are updated accounts or rates since last run, foreach (var lstNm in new string[] { ratesLstNm, accountsLstNm }) { if (incremental != false) { query = new CamlQuery(); query.ViewXml = $@" <View> <Query> <Where> <Gt> <FieldRef Name='Modified' /> <Value IncludeTimeValue='true' Type='DateTime'>{lastRunTs.ToString("yyyy-MM-ddTHH:mm:ssZ")}</Value> </Gt> </Where> </Query> <RowLimit>1</RowLimit> </View>"; var lst = cc.Web.Lists.GetByTitle(lstNm); var lic = lst.GetItems(query); cc.Load(lic); cc.ExecuteQuery(); if (lic.Count > 0) { incremental = false; } } } // populate or update charge from consumption query = new CamlQuery(); string viewXml = null; if (incremental == false) { viewXml = $@" <View><Query> <Where> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Eq> </Where> </Query></View>"; } else { viewXml = $@" <View><Query> <Where> <And> <Eq> <FieldRef Name='Cycle' /> <Value Type='DateTime'>{billingCycleStart.ToString("yyyy-MM-dd")}</Value> </Eq> <Gt> <FieldRef Name='Modified' /> <Value IncludeTimeValue='true' Type='DateTime'>{lastRunTs.ToString("yyyy-MM-ddTHH:mm:ssZ")}</Value> </Gt> </And> </Where> </Query></View>"; } query.ViewXml = viewXml; var consumptionLIC = consumptionLst.GetItems(query); cc.Load(consumptionLIC, items => items.IncludeWithDefaultProperties( item => item["HasUniqueRoleAssignments"] )); cc.Load(cc.Web.RoleDefinitions); var gc = cc.Web.SiteGroups; cc.Load(gc); var readRD = cc.Web.RoleDefinitions.GetByName("Read"); cc.ExecuteQuery(); RoleDefinition restReadRD; try { restReadRD = cc.Web.RoleDefinitions.GetByName("Restricted Read"); cc.ExecuteQuery(); } catch { restReadRD = null; } foreach (var consumptionLI in consumptionLIC) { ListItem chgItem; // check if charges exists var chgItemQuery = new CamlQuery(); chgItemQuery.ViewXml = $@" <View><Query> <Where> <Eq> <FieldRef Name='Consumption_x0020_Ref' LookupId='TRUE' /> <Value Type='Lookup'>{consumptionLI["ID"]}</Value> </Eq> </Where> </Query></View>"; var chgLIC = chgLst.GetItems(chgItemQuery); cc.Load(chgLIC); cc.ExecuteQuery(); if (chgLIC.Count > 0) { chgItem = chgLIC[0]; if (isCycleOpen && incremental != false && ((DateTime)consumptionLI["Modified"]) < ((DateTime)chgItem["Modified"])) { continue; } chgItem.ResetRoleInheritance(); cc.ExecuteQuery(); } else { // create new charges item ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation(); chgItem = chgLst.AddItem(itemCreateInfo); } // get org item var orgItemQuery = new CamlQuery(); orgItemQuery.ViewXml = $@" <View><Query> <Where> <Eq> <FieldRef Name='ID' /> <Value Type='Counter'>{((FieldLookupValue)consumptionLI["Account"]).LookupId}</Value> </Eq> </Where> </Query></View>"; var orgLst = cc.Web.Lists.GetByTitle(accountsLstNm); var orgLIC = orgLst.GetItems(orgItemQuery); cc.Load(orgLIC); // get rate item var rateItemQuery = new CamlQuery(); rateItemQuery.ViewXml = $@"<View><Query> <Where> <Eq> <FieldRef Name='ID' /> <Value Type='Counter'>{((FieldLookupValue)consumptionLI["Rate"]).LookupId}</Value> </Eq> </Where> </Query></View>"; var rateLst = cc.Web.Lists.GetByTitle(ratesLstNm); var rateLIC = rateLst.GetItems(rateItemQuery); cc.Load(rateLIC); cc.ExecuteQuery(); var orgItem = orgLIC.First(); var rateItem = rateLIC.First(); chgItem["Account"] = orgItem["Title"]; chgItem["Title"] = consumptionLI["Title"]; chgItem["Cycle"] = consumptionLI["Cycle"]; chgItem["Unit_x0020_Price"] = rateItem["Unit_x0020_Price"]; chgItem["Denominator"] = rateItem["Denominator"]; chgItem["UOM"] = rateItem["UOM"]; chgItem["Quantity"] = consumptionLI["Quantity"]; FieldLookupValue lookup = new FieldLookupValue(); lookup.LookupId = (int)consumptionLI["ID"]; chgItem["Consumption_x0020_Ref"] = lookup; // the order of list enumeration is important foreach (var lstNm in new string[] { "Account", "Rate", "Consumption" }) { KeyValuePair <string, List <KeyValuePair <string, string> > > listColumnToCopy = new KeyValuePair <string, List <KeyValuePair <string, string> > >(lstNm, listColumnsToCopy[lstNm]); if (listColumnToCopy.Value.Count <= 0) { continue; } ListItem item = null; switch (listColumnToCopy.Key) { case "Account": item = orgItem; break; case "Rate": item = rateItem; break; case "Consumption": item = consumptionLI; break; } foreach (var columnNVP in listColumnToCopy.Value) { try { if (item[columnNVP.Key] != null) { chgItem[columnNVP.Value] = item[columnNVP.Key]; } } catch { EventLog.WriteEntry(evtLogSrc, $@"Cannot copy column {columnNVP.Key} in list {listColumnToCopy.Key} for consumption ID={consumptionLI["ID"]}", EventLogEntryType.Error); } } } if (consumptionLI["Amount"] != null) { chgItem["Amount"] = consumptionLI["Amount"]; } else if (consumptionLI["Quantity"] != null && rateItem["Denominator"] != null && rateItem["Unit_x0020_Price"] != null && rateItem["Denominator"] != null && (double)rateItem["Denominator"] > 0) { var normalizedQty = (double)consumptionLI["Quantity"] / (double)rateItem["Denominator"]; try { if (rateItem["Round_x0020_Up"] != null && rateItem["Round_x0020_Up"] as Nullable <bool> == true) { normalizedQty = Math.Ceiling((double)consumptionLI["Quantity"] / (double)rateItem["Denominator"]); } } catch { EventLog.WriteEntry(evtLogSrc, $"Error calculate round up for rate ID={rateItem["ID"]}, consumption ID={consumptionLI["ID"]}", EventLogEntryType.Error); } chgItem["Amount"] = (double)rateItem["Unit_x0020_Price"] * normalizedQty; } if (chgItem.FieldValues.ContainsKey("Amount")) { chgItem.Update(); cc.ExecuteQuery(); } else { EventLog.WriteEntry(evtLogSrc, "Cannot calculate amount for consumption item " + consumptionLI["ID"], EventLogEntryType.Error); } if (!isCycleOpen) { if (!consumptionLI.HasUniqueRoleAssignments) { consumptionLI.BreakRoleInheritance(true, false); cc.ExecuteQuery(); } cc.Load(consumptionLI.RoleAssignments, items => items.Include( ra => ra.RoleDefinitionBindings.Include( rdb => rdb.Name ) )); cc.ExecuteQuery(); foreach (var ra in consumptionLI.RoleAssignments) { bool addRead = false; foreach (var rdbo in ra.RoleDefinitionBindings) { if (rdbo.Name == "Contribute") { ra.RoleDefinitionBindings.Remove(rdbo); addRead = true; } } if (addRead) { ra.RoleDefinitionBindings.Add(readRD); } ra.Update(); } cc.ExecuteQuery(); } } var chargesLst = cc.Web.Lists.GetByTitle(chargesLstNm); var chargesLIC = chargesLst.GetItems(query); cc.Load(chargesLIC, items => items.Include( item => item["Account"] , item => item["HasUniqueRoleAssignments"] )); cc.ExecuteQuery(); foreach (var chargeLI in chargesLIC) { if (chargeLI.HasUniqueRoleAssignments) { chargeLI.ResetRoleInheritance(); cc.ExecuteQuery(); } chargeLI.BreakRoleInheritance(true, false); foreach (var g in gc) { if (g.LoginName == (groupPrefix + chargeLI["Account"].ToString())) { var rdb = new RoleDefinitionBindingCollection(cc); rdb.Add(restReadRD != null ? restReadRD : readRD); chargeLI.RoleAssignments.Add(g, rdb); break; } } cc.ExecuteQuery(); } var runEndTime = DateTime.Now; EventLog.WriteEntry(evtLogSrc, $"Run ended {runEndTime}, lasting {(runEndTime - runStartTime).TotalMinutes.ToString("0.00")} minutes.", EventLogEntryType.Information); System.IO.File.Delete(lastRunFileName); System.IO.File.WriteAllLines(lastRunFileName, new string[] { billingCycleStart.ToShortDateString(), runStartTime.ToString() }); } catch (Exception ex) { EventLog.WriteEntry(evtLogSrc, $"{ex}", EventLogEntryType.Error); throw; } }