private int GetNewSequenceNumber(NorthwindConfig config, OleDbConnection connection) { //Sequence sequence; //sequence = new Data.Sequence(); int sequenceNumber = -1; //SequenceTableAdapter sequenceTableAdapter; //sequenceTableAdapter = new SequenceTableAdapter(); //Sequence.SequenceRow row = sequence._Sequence.NewSequenceRow(); //row.Date = DateTime.Now; //sequence._Sequence.AddSequenceRow(row); //sequenceTableAdapter.Connection = connection; //sequenceTableAdapter.Update(sequence._Sequence); OleDbCommand CmdSequence = new OleDbCommand("INSERT INTO Sequence ( [Date] ) SELECT Now()", connection); CmdSequence.ExecuteNonQuery(); OleDbCommand Cmd = new OleDbCommand("SELECT @@IDENTITY", connection); object lastid = Cmd.ExecuteScalar(); sequenceNumber = (int)lastid; return(sequenceNumber); }
public void DoWork(IRequest request) { NorthwindConfig config = new NorthwindConfig(); config.CurrencyCode = "EUR"; config.CrmUser = "******"; config.Path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Northwind"); string fileName = Path.Combine(config.Path, "Northwind.mdb"); FileInfo fileInfo = new FileInfo(fileName); string link = _requestContext.ContractLink + "-"; DatasetFeedEntry entry = new DatasetFeedEntry(); entry.Id = link; entry.Title = fileInfo.Name; entry.Published = fileInfo.CreationTime; entry.Updated = fileInfo.LastAccessTime; entry.Link = link; Feed<DatasetFeedEntry> feed = new Feed<DatasetFeedEntry>(); feed.Id = "Available Datasets"; feed.Title = "Available Datasets"; feed.Entries.Add(entry); request.Response.Feed = feed; }
public Pricing CheckPrice(Pricing PricingInformation, NorthwindConfig northwindConfig) { Pricing result; Product product = new Product(); result = product.CheckPrice(PricingInformation, northwindConfig); return result; }
/// <summary> /// of following entities: /// • Account /// • Order /// </summary> /// <param name="EntityName"></param> /// <param name="TransactionData"></param> /// <param name="config"></param> /// <returns></returns> public TransactionResult[] ExecuteTransactions(string EntityName, Transaction[] TransactionData, NorthwindConfig config) { int seqenceID; try { EntityBase entity = EntityFactory.GetEntity(EntityName); if (entity == null) throw new Exception(string.Format(Resources.ErrorMessages_OperationNotImplementedForEntity, EntityName)); seqenceID = config.SequenceNumber; return entity.ExecuteTransactions(TransactionData, config); } catch (Exception e) { TransactionResult[] results = new TransactionResult[1]; results[0] = new TransactionResult(); results[0].Status = TransactionStatus.FatalError; results[0].EntityName = EntityName; results[0].Message = e.ToString(); return results; } }
/// <summary> ///• Account /// • Order /// • Product /// • ProductFamily /// • Price /// • UnitOfMesure /// • UnitOfMeasureFamily /// </summary> /// <param name="EntityName">The name of the entity</param> /// <param name="Token"></param> /// <param name="config">the configuration object</param> /// <returns></returns> public ChangeLog GetChangeLog(string entityName, string token, NorthwindConfig config) { Token intToken; // create an new token for the requested entity intToken = new Token(new Identity(entityName, ""), 0, true); // if an serialzed tokenstring passed in, deserialize and use this one if (!((token == null) || (token.Length == 0))) { //token = (Token)XmlHelper.DeserializeXmlToObject(token, Token); intToken = (Token)Token.DeserializeToken(token); } // get a new entity object of the requestet entity EntityBase entity = EntityFactory.GetEntity(entityName); // if the entityname is not supported by the connector an error will thrown if (entity == null) { throw new Exception(string.Format(Resources.ErrorMessages_OperationNotImplementedForEntity, entityName)); } // get the changelog an an entity return(entity.GetChangelog(intToken, config)); }
/// <summary> /// /// </summary> /// <param name="OrderDetails"></param> /// <param name="config"></param> /// <returns></returns> public PricingDetail GetPricingDetails(OrderDetailInformation OrderDetails, NorthwindConfig config) { PricingDetail result; Product product = new Product(); result = product.GetPricingDetails(OrderDetails, config); return(result); }
public Pricing CheckPrice(Pricing PricingInformation, NorthwindConfig northwindConfig) { Pricing result; Product product = new Product(); result = product.CheckPrice(PricingInformation, northwindConfig); return(result); }
/// <summary> /// There are three authentication types supported by CRM. /// When CRM connects to an ERP system for the first time it calls GetAuthenticationScheme /// to find out what authentication type is supported by the ERP system. /// Subsequent calls will use the supported authentication type. /// </summary> /// <returns></returns> public AuthenticationResult GetAuthenticationScheme(NorthwindConfig config) { AuthenticationResult result = new AuthenticationResult(); result.AuthenticationOnEveryCall = true; result.PasswordHandling = PasswordType.ClearText; return(result); }
/// <summary> /// GetConfiguration is called after GetAuthentication when a new integration is created. /// It is also called when an integration is enabled. /// GetConfiguration is a request to the ERP system for configuration information. /// This will be used to populate the configuration area of the integration in CRM. /// </summary> /// <returns>The ERP system responds with a GetConfigurationResponse. /// GetConfigurationResponse contains a Configuration structure. /// The contents of a Configuration structure are: /// • Version – The version of the contract supported. /// The version supported in the 6.0.1 release is version 1.0. /// • Product Name – The name of the ERP system, eg MAS200, Line 50. /// • ERP Schema – This is a complex type used to feed back /// the xsd for the webservices interface. /// The xsd must conform to the specification defined by sage CRM. /// </returns> public Configuration GetConfiguration(NorthwindConfig nwConfig) { string schemastring; List <Document> documents = EntityFactory.GetSupportedDocumentTemplates(); Configuration config = new Configuration(); config.ProductName = "Northwind"; config.SchemaVersion = nwConfig.Version; XmlDocument xmlDoc = new XmlDocument(); XmlSchema schema = new XmlSchema(); schema.ElementFormDefault = XmlSchemaForm.Qualified; schema.TargetNamespace = "http://schemas.sage.com/sis/Northwind/2007/05/Synch"; //schema.Namespaces.Add("xs", XmlSchema.Namespace); schema.Namespaces.Add("tns", schema.TargetNamespace); foreach (Document doc in documents) { schema.Items.Add(doc.GetSchemaElement()); } schemastring = XmlSerializationHelpers.SerializeObjectToXml(schema); xmlDoc.LoadXml(schemastring); config.SyncSchema = xmlDoc.DocumentElement; #region RTDV // create and initialize rtdv schema schema = new XmlSchema(); schema.Id = "RTDV"; schema.TargetNamespace = "http://schemas.sage.com/sis/Northwind/2007/05/RTDV"; schema.ElementFormDefault = XmlSchemaForm.Qualified; schema.Namespaces.Add("mstns", schema.TargetNamespace); // append elements to schema RTDVBase[] rtdvArray = RTDVFactory.GetRTDVAll(); // get instances of all RTDVs foreach (RTDVBase rtdv in rtdvArray) // iterate through all RTDVs and get their schema element { schema.Items.Add(rtdv.GetXmlSchemaElement()); // append schema element to rtdv schema } xmlDoc = new XmlDocument(); schemastring = XmlSerializationHelpers.SerializeObjectToXml(schema); xmlDoc.LoadXml(schemastring); config.RTDSchema = xmlDoc.DocumentElement; // set rtdv schema to config #endregion return(config); }
public TransformationBase(RequestContext context, SupportedResourceKinds resourceKind) { _context = context; _datasetLink = _context.DatasetLink; _config = _context.Config; _resourceKind = resourceKind; _resourceKindString = _resourceKind.ToString(); _originApplication = _datasetLink + _resourceKindString; _correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); }
private int GetLastSequenceNumber(NorthwindConfig config) { int sequenceNumber = -1; using (OleDbConnection connection = new OleDbConnection(config.ConnectionString)) { connection.Open(); sequenceNumber = GetLastSequenceNumber(config, connection); } return(sequenceNumber); }
/// <summary> /// OpenSession is called at the start of every call to the ERP system. /// If OpenSession returns a token, /// then it is passed in the header for subsequent calls. /// </summary> /// <returns></returns> public SessionOpenResult OpenSession(NorthwindConfig config) { SessionOpenResult result = new SessionOpenResult(); DateTime now = DateTime.Now; string sessionExtention = "." + now.Year.ToString() + now.Month.ToString() + now.Day.ToString() + "." + now.Hour.ToString() + "." + now.Minute.ToString() + "." + now.Second.ToString() + "." + now.Millisecond.ToString(); result.SessionKey = config.LastSequenceNumber.ToString() + sessionExtention; return(result); }
private int GetLastSequenceNumber(NorthwindConfig config, OleDbConnection connection) { int sequenceNumber = -1; OleDbCommand Cmd = new OleDbCommand("SELECT Max(Sequence.ID) AS MaxOfID FROM Sequence", connection); object lastid = Cmd.ExecuteScalar(); if (lastid == null || lastid == DBNull.Value) { sequenceNumber = 0; } else { sequenceNumber = (int)lastid; } return(sequenceNumber); }
/// <summary> /// GetCustomisations is called after GetConfiguration, /// either when a new integration is being created or when an integration is enabled. /// It is a request to the ERP system for customisation information. /// </summary> /// <returns>The ERP system responds to a GetCustomisations request, /// with a GetCustomisationsReponse, /// which contains a list of ERPCustomisations changes</returns> public ERPCustomisations GetCustomisations(NorthwindConfig nwConfig) { ERPCustomisations result; result = new ERPCustomisations(); result.Version = nwConfig.CustomisationVersion; XmlDocument resultDoc = new XmlDocument(); resultDoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?><getcustomisationsresponse/>"); AddCustomisations(ref resultDoc, "AdditionalStockDetails"); AddCustomisations(ref resultDoc, "ProductsPurchased"); AddCustomisations(ref resultDoc, "SalesInvoices"); AddCustomisations(ref resultDoc, "AccountTab"); AddCustomisations(ref resultDoc, "ErpSelections"); AddSelesReps(ref resultDoc, nwConfig); result.CustomisationData = resultDoc.DocumentElement; return(result); }
private SalesOrderLinePayload GetLineItem(DataSets.Order.CalculatedOrderDetailsRow row, NorthwindConfig config) { #region Declarations SalesOrderLinePayload payload; string id; decimal discountPercentage; #endregion id = row.OrderID.ToString() + "-" + row.ProductID.ToString(); payload = new SalesOrderLinePayload(); payload.LocalID = id; //payload.SyncUuid = GetUuid(id, "", SupportedResourceKinds.salesOrderLines); payload.SalesOrderLinetype.applicationID = id; payload.ForeignIds.Add("commodity", row.ProductID.ToString()); payload.ForeignIds.Add("salesOrder", row.OrderID.ToString()); payload.ForeignIds.Add("unitOfMeasure", row.ProductID.ToString()); payload.SalesOrderLinetype.quantitySpecified = true; payload.SalesOrderLinetype.quantity = row.IsQuantityNull() ? Convert.ToInt16(0) : row.Quantity; payload.SalesOrderLinetype.initialPriceSpecified = true; payload.SalesOrderLinetype.initialPrice = row.IsUnitPriceNull() ? new decimal(0) : row.UnitPrice; payload.SalesOrderLinetype.orderLineDiscountPercentSpecified = true; payload.SalesOrderLinetype.orderLineDiscountPercent = row.IsDiscountNull() ? (decimal)0 : Convert.ToDecimal(row.Discount); payload.SalesOrderLinetype.discountTotalSpecified = true; payload.SalesOrderLinetype.discountTotal = payload.SalesOrderLinetype.initialPrice * (decimal)payload.SalesOrderLinetype.orderLineDiscountPercent; payload.SalesOrderLinetype.costTotalSpecified = true; payload.SalesOrderLinetype.costTotal = (decimal)payload.SalesOrderLinetype.initialPrice * (1 - payload.SalesOrderLinetype.orderLineDiscountPercent); payload.SalesOrderLinetype.netTotalSpecified = true; payload.SalesOrderLinetype.netTotal = Convert.ToDecimal(payload.SalesOrderLinetype.quantity) * Convert.ToDecimal(payload.SalesOrderLinetype.costTotal); return payload; }
/// <summary> /// The Constructor. /// </summary> public NorthwindConnector() { _config = new NorthwindConfig("-"); }
/// <summary> /// ViewRealTimeData is a request to the ERP system for real time viewing data from the ERP system. /// </summary> /// <param name="queryFields">An array of query fields that represent the parameters needed for the request.</param> /// <param name="config">the configuration object</param> /// <returns>The response to ViewRealTimeData is a XmlDocument, which contains a list of real time data.</returns> public ViewRealTimeDataResult ViewRealTimeData(string entityName, string[] selectFields, SearchField[] searchFields, string[] orderFields, int rowsPerPage, int pageNumber, NorthwindConfig northwindConfig) { // declarations RTDVBase rdtv; rdtv = RTDVFactory.GetRTDV(entityName); if (rdtv == null) throw new Exception(string.Format(Resources.ErrorMessages_RTDVNotImplemented, entityName)); if (orderFields == null) orderFields = new string[0]; if (searchFields == null) searchFields = new SearchField[0]; if (selectFields == null) selectFields = new string[0]; ViewRealTimeDataResult result = new ViewRealTimeDataResult(); result.RealTimeData = rdtv.ViewRealTimeData(entityName, selectFields, searchFields, orderFields, rowsPerPage, pageNumber, northwindConfig); return result; }
/// <summary> /// /// </summary> /// <param name="OrderDetails"></param> /// <param name="config"></param> /// <returns></returns> public PricingDetail GetPricingDetails(OrderDetailInformation OrderDetails, NorthwindConfig config) { PricingDetail result; Product product = new Product(); result = product.GetPricingDetails(OrderDetails, config); return result; }
/// <summary> /// GetConfiguration is called after GetAuthentication when a new integration is created. /// It is also called when an integration is enabled. /// GetConfiguration is a request to the ERP system for configuration information. /// This will be used to populate the configuration area of the integration in CRM. /// </summary> /// <returns>The ERP system responds with a GetConfigurationResponse. /// GetConfigurationResponse contains a Configuration structure. /// The contents of a Configuration structure are: /// • Version – The version of the contract supported. /// The version supported in the 6.0.1 release is version 1.0. /// • Product Name – The name of the ERP system, eg MAS200, Line 50. /// • ERP Schema – This is a complex type used to feed back /// the xsd for the webservices interface. /// The xsd must conform to the specification defined by sage CRM. /// </returns> public Configuration GetConfiguration(NorthwindConfig nwConfig) { string schemastring; List<Document> documents = EntityFactory.GetSupportedDocumentTemplates(); Configuration config = new Configuration(); config.ProductName = "Northwind"; config.SchemaVersion = nwConfig.Version; XmlDocument xmlDoc = new XmlDocument(); XmlSchema schema = new XmlSchema(); schema.ElementFormDefault = XmlSchemaForm.Qualified; schema.TargetNamespace = "http://schemas.sage.com/sis/Northwind/2007/05/Synch"; //schema.Namespaces.Add("xs", XmlSchema.Namespace); schema.Namespaces.Add("tns", schema.TargetNamespace); foreach (Document doc in documents) schema.Items.Add(doc.GetSchemaElement()); schemastring = XmlSerializationHelpers.SerializeObjectToXml(schema); xmlDoc.LoadXml(schemastring); config.SyncSchema= xmlDoc.DocumentElement; #region RTDV // create and initialize rtdv schema schema = new XmlSchema(); schema.Id = "RTDV"; schema.TargetNamespace = "http://schemas.sage.com/sis/Northwind/2007/05/RTDV"; schema.ElementFormDefault = XmlSchemaForm.Qualified; schema.Namespaces.Add("mstns", schema.TargetNamespace); // append elements to schema RTDVBase[] rtdvArray = RTDVFactory.GetRTDVAll(); // get instances of all RTDVs foreach (RTDVBase rtdv in rtdvArray) // iterate through all RTDVs and get their schema element schema.Items.Add(rtdv.GetXmlSchemaElement()); // append schema element to rtdv schema xmlDoc = new XmlDocument(); schemastring = XmlSerializationHelpers.SerializeObjectToXml(schema); xmlDoc.LoadXml(schemastring); config.RTDSchema = xmlDoc.DocumentElement; // set rtdv schema to config #endregion return config; }
// Asynchronous called method private void Execute(NorthwindConfig config, Digest targetDigest) { #region Declaration SdataContext sdataContext; SupportedResourceKinds resource; IAppBookmarkInfoStore appBookmarkInfoStore; ICorrelatedResSyncInfoStore correlatedResSyncInfoStore; ISyncSyncDigestInfoStore syncDigestStore; ISynctickProvider tickProvider; string resourceKind; string EndPoint; int nexttick = 1; Token lastToken; Token nextToken; Identity[] changedIdentites; IFeedEntryEntityWrapper wrapper; #endregion #region init sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); EndPoint = _parentPerformer._requestContext.DatasetLink + resourceKind; appBookmarkInfoStore = NorthwindAdapter.StoreLocator.GetAppBookmarkStore(sdataContext); correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(sdataContext); syncDigestStore = NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); tickProvider = NorthwindAdapter.StoreLocator.GettickProvider(sdataContext); wrapper = FeedEntryWrapperFactory.Create(resource, _parentPerformer._requestContext); #endregion #region get last token or create a new one if (!appBookmarkInfoStore.Get<Token>(resourceKind, out lastToken)) { lastToken = new Token(); lastToken.InitRequest = true; } #endregion #region Get local identities of changed entries since last synchronisation changedIdentites = wrapper.Entity.GetLastChanges(lastToken, config, out nextToken); #endregion if (resource == SupportedResourceKinds.phoneNumbers) { #region workaround for phones for (int index = 0; index < changedIdentites.Length; index++) { string phoneid = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix; string faxId = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix; // receive the resource payloads for the phone id and for the fax id // so that we can calculate their current etags. FeedEntry phoneResourcePayloadContainer = wrapper.GetFeedEntry(phoneid); FeedEntry faxResourcePayloadConatainer = wrapper.GetFeedEntry(faxId); string etag; CorrelatedResSyncInfo[] correlatedResSyncInfos; #region Phone if (phoneResourcePayloadContainer != null) { // calculate etag of the resource etag = EtagServices.ComputeEtag(phoneResourcePayloadContainer, true); // new etag // retrieve correlations for the current identity from synch storage correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { phoneid }); // if no correlation exists AND resource has been deleted: // -> continue with next id // else if no correlation exists: // -> get next tick, create new correlation and add correlation to synch store // otherwise and if the etag stored in synch store is different than etag previously calculated: // -> get next tick, modify existing correlation and update it in synch store. if (correlatedResSyncInfos.Length == 0 && phoneResourcePayloadContainer.IsDeleted) { continue; } else if (correlatedResSyncInfos.Length == 0) { nexttick = tickProvider.CreateNexttick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), EndPoint, nexttick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(phoneid, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nexttick = tickProvider.CreateNexttick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nexttick; correlatedResSyncInfos[0].ResSyncInfo.EndPoint = EndPoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } #endregion #region Fax if (faxResourcePayloadConatainer != null) { // calculate etag of the resource etag = EtagServices.ComputeEtag(faxResourcePayloadConatainer, true); // new etag // retrieve correlations for the current identity from synch storage correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { faxId }); // if no correlation exists AND resource has been deleted: // -> continue with next id // else if no correlation exists: // -> get next tick, create new correlation and add correlation to synch store // otherwise and if the etag stored in synch store is different than etag previously calculated: // -> get next tick, modify existing correlation and update it in synch store. if (correlatedResSyncInfos.Length == 0 && faxResourcePayloadConatainer.IsDeleted) { continue; } else if (correlatedResSyncInfos.Length == 0) { nexttick = tickProvider.CreateNexttick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), EndPoint, nexttick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(faxId, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nexttick = tickProvider.CreateNexttick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nexttick; correlatedResSyncInfos[0].ResSyncInfo.EndPoint = EndPoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } #endregion } #endregion } else { string id; FeedEntry resourcePayloadContainer; CorrelatedResSyncInfo[] correlatedResSyncInfos; string etag; // iterate through the collection of ids of all changed resources. for (int index = 0; index < changedIdentites.Length; index++) { // current id from iterated collection id = changedIdentites[index].Id; // get resource payload container for the current identity so that we can calculated the // etag. // continue with next identity if no resource was found. resourcePayloadContainer = wrapper.GetFeedEntry(id); // calculate etag of the current resource payload etag = EtagServices.ComputeEtag(resourcePayloadContainer, true); // retrieve correlations for the current identity from synch storage correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { id }); // if no correlation exists AND resource has been deleted: // -> continue with next id // else if no correlation exists: // -> get next tick, create new correlation and add correlation to synch store // otherwise and if the etag stored in synch store is different than etag previously calculated: // -> get next tick, modify existing correlation and update it in synch store. if (resourcePayloadContainer == null || (correlatedResSyncInfos.Length == 0 && resourcePayloadContainer.IsDeleted)) { continue; } else if (correlatedResSyncInfos.Length == 0) { nexttick = tickProvider.CreateNexttick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), EndPoint, nexttick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(id, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nexttick = tickProvider.CreateNexttick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nexttick; correlatedResSyncInfos[0].ResSyncInfo.EndPoint = EndPoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } } #region store next token appBookmarkInfoStore.Put(resourceKind, nextToken); #endregion // set tracking phase lock (_parentPerformer._asyncStateObj) { _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.GETCHANGESBYtick; } if (null != targetDigest) { ICorrelatedResSyncInfoEnumerator enumerator; List<string> EndPoints = new List<string>(); #warning remove this workaround if (targetDigest.Entries != null) { foreach (DigestEntry targetDigestEntry in targetDigest.Entries) { EndPoints.Add(targetDigestEntry.EndPoint); enumerator = correlatedResSyncInfoStore.GetSincetick(resourceKind, targetDigestEntry.EndPoint, ((int)targetDigestEntry.Tick) - 1); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } } SyncDigestInfo sourceSyncDigestInfo = syncDigestStore.Get(resourceKind); foreach (SyncDigestEntryInfo digestEntry in sourceSyncDigestInfo) { if (EndPoints.Contains(digestEntry.EndPoint)) continue; EndPoints.Add(digestEntry.EndPoint); enumerator = correlatedResSyncInfoStore.GetSincetick(resourceKind, digestEntry.EndPoint, -1); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } if (!EndPoints.Contains(EndPoint)) { enumerator = correlatedResSyncInfoStore.GetSincetick(resourceKind, EndPoint, -1); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } } // Set tracking phase to FINISH lock (_parentPerformer._asyncStateObj.Tracking) { _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.FINISH; } }
/// <summary> /// The Constructor. /// </summary> public NorthwindConnector() { _config = new NorthwindConfig(); }
/// <summary> /// ViewRealTimeData is a request to the ERP system for real time viewing data from the ERP system. /// </summary> /// <param name="queryFields">An array of query fields that represent the parameters needed for the request.</param> /// <param name="config">the configuration object</param> /// <returns>The response to ViewRealTimeData is a XmlDocument, which contains a list of real time data.</returns> public ViewRealTimeDataResult ViewRealTimeData(string entityName, string[] selectFields, SearchField[] searchFields, string[] orderFields, int rowsPerPage, int pageNumber, NorthwindConfig northwindConfig) { // declarations RTDVBase rdtv; rdtv = RTDVFactory.GetRTDV(entityName); if (rdtv == null) { throw new Exception(string.Format(Resources.ErrorMessages_RTDVNotImplemented, entityName)); } if (orderFields == null) { orderFields = new string[0]; } if (searchFields == null) { searchFields = new SearchField[0]; } if (selectFields == null) { selectFields = new string[0]; } ViewRealTimeDataResult result = new ViewRealTimeDataResult(); result.RealTimeData = rdtv.ViewRealTimeData(entityName, selectFields, searchFields, orderFields, rowsPerPage, pageNumber, northwindConfig); return(result); }
/// <summary> /// of following entities: /// • Account /// • Order /// </summary> /// <param name="EntityName"></param> /// <param name="TransactionData"></param> /// <param name="config"></param> /// <returns></returns> public TransactionResult[] ExecuteTransactions(string EntityName, Transaction[] TransactionData, NorthwindConfig config) { int seqenceID; try { EntityBase entity = EntityFactory.GetEntity(EntityName); if (entity == null) { throw new Exception(string.Format(Resources.ErrorMessages_OperationNotImplementedForEntity, EntityName)); } seqenceID = config.SequenceNumber; return(entity.ExecuteTransactions(TransactionData, config)); } catch (Exception e) { TransactionResult[] results = new TransactionResult[1]; results[0] = new TransactionResult(); results[0].Status = TransactionStatus.FatalError; results[0].EntityName = EntityName; results[0].Message = e.ToString(); return(results); } }
private SalesInvoiceLineFeedEntry GetLineItem(Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.CalculatedOrderDetailsRow row, NorthwindConfig config) { #region Declarations SalesInvoiceLineFeedEntry payload; string id; decimal discountPercentage; #endregion id = row.OrderID.ToString() + "-" + row.ProductID.ToString(); payload = new SalesInvoiceLineFeedEntry(); payload.Key = id; payload.Id = GetSDataId(payload.Key, SupportedResourceKinds.salesInvoiceLines); payload.UUID = GetUuid(id, "", SupportedResourceKinds.salesInvoiceLines); /*payload.commodity = (CommodityPayload)PayloadFactory.CreateResourcePayload( SupportedResourceKinds.commodities, row.ProductID.ToString(), _context.DatasetLink, true);*/ payload.commodity = new CommodityFeedEntry(); payload.commodity.Key = row.ProductID.ToString(); payload.commodity.Id = GetSDataId(payload.commodity.Key, SupportedResourceKinds.commodities); payload.commodity.UUID = GetUuid(row.ProductID.ToString(), "", SupportedResourceKinds.commodities); //payload.SalesInvoiceLinetype.salesInvoice = (SalesInvoicePayload)PayloadFactory.CreateResourcePayload( // SupportedResourceKinds.salesInvoices, row.OrderID.ToString(), _context.DatasetLink, true); //payload.SalesInvoiceLinetype.salesInvoice.Uuid = GetUuid(row.OrderID.ToString(), "", SupportedResourceKinds.salesInvoices); /*payload.unitOfMeasure = (UnitOfMeasurePayload)PayloadFactory.CreateResourcePayload( SupportedResourceKinds.unitsOfMeasure, row.ProductID.ToString(), _context.DatasetLink, true);*/ payload.unitOfMeasure = new UnitOfMeasureFeedEntry(); payload.unitOfMeasure.Key = row.ProductID.ToString(); payload.unitOfMeasure.Id = GetSDataId(payload.unitOfMeasure.Key, SupportedResourceKinds.unitsOfMeasure); payload.unitOfMeasure.UUID = GetUuid(row.ProductID.ToString(), "", SupportedResourceKinds.unitsOfMeasure); payload.quantity = row.IsQuantityNull() ? Convert.ToInt16(0) : row.Quantity; payload.initialPrice = row.IsUnitPriceNull() ? new decimal(0) : row.UnitPrice; payload.invoiceLineDiscountPercent = row.IsDiscountNull() ? (decimal)0 : Convert.ToDecimal(row.Discount); payload.discountTotal = (decimal)payload.initialPrice * (decimal)payload.invoiceLineDiscountPercent; payload.costTotal = (decimal)payload.initialPrice * (1 - payload.invoiceLineDiscountPercent); payload.netTotal = Convert.ToDecimal(payload.quantity) * Convert.ToDecimal(payload.costTotal); return payload; }
/// <summary> /// There are three authentication types supported by CRM. /// When CRM connects to an ERP system for the first time it calls GetAuthenticationScheme /// to find out what authentication type is supported by the ERP system. /// Subsequent calls will use the supported authentication type. /// </summary> /// <returns></returns> public AuthenticationResult GetAuthenticationScheme(NorthwindConfig config) { AuthenticationResult result = new AuthenticationResult(); result.AuthenticationOnEveryCall = true; result.PasswordHandling = PasswordType.ClearText; return result; }
public void DoWork(NorthwindConfig config, SyncFeed feed) { ExecuteDelegate worker = new ExecuteDelegate(Execute); AsyncCallback completedCallback = new AsyncCallback(ExecuteCompletedCallback); AsyncOperation async = AsyncOperationManager.CreateOperation(null); // Begin asynchronous method call worker.BeginInvoke(config, feed, completedCallback, async); }
/// <summary> ///• Account /// • Order /// • Product /// • ProductFamily /// • Price /// • UnitOfMesure /// • UnitOfMeasureFamily /// </summary> /// <param name="EntityName">The name of the entity</param> /// <param name="Token"></param> /// <param name="config">the configuration object</param> /// <returns></returns> public ChangeLog GetChangeLog(string entityName, string token, NorthwindConfig config) { Token intToken; // create an new token for the requested entity intToken = new Token(new Identity(entityName, ""), 0, true); // if an serialzed tokenstring passed in, deserialize and use this one if (!((token == null) || (token.Length == 0))) //token = (Token)XmlHelper.DeserializeXmlToObject(token, Token); intToken = (Token)Token.DeserializeToken(token); // get a new entity object of the requestet entity EntityBase entity = EntityFactory.GetEntity(entityName); // if the entityname is not supported by the connector an error will thrown if (entity == null) throw new Exception(string.Format(Resources.ErrorMessages_OperationNotImplementedForEntity, entityName)); // get the changelog an an entity return entity.GetChangelog(intToken, config); }
// Asynchronous called method private void Execute(NorthwindConfig config, SyncFeed feed) { #region Declarations SdataContext sdataContext; SupportedResourceKinds resource; IAppBookmarkInfoStore appBookmarkInfoStore; ICorrelatedResSyncInfoStore correlatedResSyncInfoStore; ISyncSyncDigestInfoStore syncDigestStore; GuidConverter guidConverter = new GuidConverter(); string resourceKind; string endpoint; SyncFeedDigest sourceDigest; SyncDigestInfo targetDigest; IEntityWrapper wrapper; #endregion #region init sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); endpoint = _parentPerformer._requestContext.DatasetLink + resourceKind; appBookmarkInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetAppBookmarkStore(sdataContext); correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(sdataContext); syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); sourceDigest = feed.Digest; targetDigest = syncDigestStore.Get(resourceKind); wrapper = EntityWrapperFactory.Create(resource, _parentPerformer._requestContext); #endregion #region process entries bool sourceIsDeleteMode; SdataTransactionResult sdTrResult; SyncState sourceState; SyncState targetState; foreach (SyncFeedEntry entry in feed.Entries) { sdTrResult = null; try { // Check whether the source entry had been deleted. // if not we expect a payload! // The variable 'sourceIsDeleteMode' holds the result of this check for later calls. if (entry.HttpMethod.Equals("DELETE", StringComparison.InvariantCultureIgnoreCase)) sourceIsDeleteMode = true; else if (null == entry.Payload) throw new Exception("Payload missing."); else sourceIsDeleteMode = false; // set the uuid to the payload.SyncUuid property if (!sourceIsDeleteMode) { entry.Payload.SyncUuid = entry.Uuid; } // get the source syncstate sourceState = entry.SyncState; // Look into the store to get all correlations of the uuid received from source CorrelatedResSyncInfo[] corelations = correlatedResSyncInfoStore.GetByUuid(resourceKind, new Guid[] { entry.Uuid }); if (corelations.Length == 0) { if (sourceIsDeleteMode) { // the source entry had been deleted and no correlation exists for this // entry in the target. // So we do nothing here. sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.OK; sdTrResult.HttpMessage = "OK"; sdTrResult.HttpMethod = "DELETE"; sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } else { // no target entry exists for the updated or added source entry. // So we add the source entry to the application and add a new correlation to the sync store. // If this operation fails we will have to set the result state to conflict. try { // add the entry to application sdTrResult = wrapper.Add(entry.Payload, entry.SyncLinks); if ((sdTrResult != null) && ((sdTrResult.HttpStatus == HttpStatusCode.OK) || (sdTrResult.HttpStatus == HttpStatusCode.Created))) { string etag = EtagServices.ComputeEtag(entry.Payload, true); ResSyncInfo resSyncInfo = new ResSyncInfo(entry.Uuid, entry.SyncState.Endpoint, entry.SyncState.Tick, etag, entry.SyncState.Stamp); CorrelatedResSyncInfo correlatedResSyncInfo = new CorrelatedResSyncInfo(sdTrResult.LocalId, resSyncInfo); // store the new correlation to the sync store correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfo); // update the sync digest entry if the tick of the source entry is newer than the actual tick of the target. syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfo.ResSyncInfo); } } catch (Exception e) { // in case of an unexpected error while adding a new entry to target // we create a transaction result with the state 'Conflict' sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.Conflict; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpMessage = e.ToString(); sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } } } else { // a correlation was found for the source entry. #region update or delete try { bool doUpdate = false; //bool doDelete = false; bool isConflict = true; // set the LocalID from correlation to the entry.Payload.LocalID property // only if source had not been deleted. if (!sourceIsDeleteMode) { entry.Payload.LocalID = corelations[0].LocalId; } targetState = Helper.GetSyncState( corelations[0]); //If sourceState.endpoint = targetState.endpoint, //there is no conflict and the update must be applied //if sourceState.tick > targetState.tick. if (targetState.Endpoint.Equals(sourceState.Endpoint, StringComparison.InvariantCultureIgnoreCase)) { isConflict = false; if (sourceState.Tick > targetState.Tick) { //if (!sourceIsDeleteMode) doUpdate = true; //else // doDelete = true; } } else { SyncState sourceDigestSyncState = Helper.GetSyncState(sourceDigest, targetState.Endpoint); ; SyncState targetDigestSyncState = Helper.GetSyncState(targetDigest, sourceState.Endpoint); //If targetState is contained in sourceDigest, //i.e. if sourceDigest has a digest entry E such that E.endpoint = targetState.endpoint //and E.tick >= targetState.tick, there is no conflict and the update must be applied. if (sourceDigestSyncState != null) { if (sourceDigestSyncState.Tick > targetState.Tick) { doUpdate = true; isConflict = false; } } //If sourceState is contained in targetDigest, //i.e. if targetDigest has a digest entry E such that E.endpoint = sourceState.endpoint //and E.tick >= sourceState.tick, there is no conflict and the update must be ignored //(target has the most recent version). if (targetDigestSyncState != null) { if (targetDigestSyncState.Tick > sourceState.Tick) { doUpdate = false; isConflict = false; } } //Otherwise (targetState not contained in sourceDigest, sourceState not contained in targetDigest), //there is a conflict. if ((sourceDigestSyncState == null) && (targetDigestSyncState == null)) isConflict = true; } //****************** Conflict **************** //In case of conflict, the target endpoint uses the following algorithm to resolve the conflict: //Let sourceEntry be the sourceDigest digest entry such that sourceEntry.endpoint = sourceState.endpoint. //Let targetEntry be the targetDigest digest entry such that targetEntry.endpoint = targetState.endpoint. //If sourceEntry .conflictPriority <> targetEntry .conflictPriority, the side with lowest priority wins. if(isConflict) { int sourceConflictPriority = Helper.GetConflictPriority(sourceDigest, sourceState.Endpoint); int targetConflictPriority = Helper.GetConflictPriority(targetDigest, targetState.Endpoint); if (sourceConflictPriority > targetConflictPriority) { doUpdate = true; } else if (sourceConflictPriority < targetConflictPriority) { doUpdate = false; } else { //Otherwise (sourceEntry .conflictPriority = targetEntry .conflictPriority), //then sourceState.stamp and targetState.stamp are compared //and the entry with the most recent timestamp wins. if (sourceState.Stamp > targetState.Stamp) { doUpdate = true; } } } ResSyncInfo resSyncInfo = new ResSyncInfo(entry.Uuid, entry.SyncState.Endpoint, entry.SyncState.Tick, "", entry.SyncState.Stamp); if (doUpdate && !sourceIsDeleteMode) { // update the entry in the application and update the sync store sdTrResult = wrapper.Update(entry.Payload, entry.SyncLinks); if ((sdTrResult != null) && (sdTrResult.HttpStatus == HttpStatusCode.OK)) { string etag = EtagServices.ComputeEtag(entry.Payload, true); resSyncInfo = new ResSyncInfo(entry.Uuid, entry.SyncState.Endpoint, entry.SyncState.Tick, etag, entry.SyncState.Stamp); CorrelatedResSyncInfo correlatedResSyncInfo = new CorrelatedResSyncInfo(sdTrResult.LocalId, resSyncInfo); correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfo); } } else if (!doUpdate && !sourceIsDeleteMode) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.Conflict; sdTrResult.HttpMethod = "PUT"; sdTrResult.HttpMessage = ""; sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } else if (doUpdate && sourceIsDeleteMode) { // delete the entry in the application and update the sync store // we do not support nested deletion. So only TradingAccounts and SalesOrders can be deleted. if (resource == SupportedResourceKinds.tradingAccounts || resource == SupportedResourceKinds.salesOrders) { sdTrResult = wrapper.Delete(corelations[0].LocalId); if ((sdTrResult != null) && (sdTrResult.HttpStatus == HttpStatusCode.OK)) { correlatedResSyncInfoStore.Delete(resource.ToString(), corelations[0].ResSyncInfo.Uuid); } } else { // this does not correspond to real fact, what we did at target side! sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.OK; sdTrResult.HttpMessage = "OK"; sdTrResult.HttpMethod = "DELETE"; sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } } else { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.Conflict; sdTrResult.HttpMessage = ""; sdTrResult.HttpMethod = "DELETE"; sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } syncDigestStore.PersistNewer(resourceKind, resSyncInfo); } catch (Exception e) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.Conflict; sdTrResult.HttpMethod = "PUT"; sdTrResult.HttpMessage = e.ToString(); sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } #endregion } } catch (Exception e) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpStatus = HttpStatusCode.Conflict; sdTrResult.HttpMessage = e.ToString(); sdTrResult.ResourceKind = resource; sdTrResult.Uuid = entry.Uuid; } #region store transaction result if (sdTrResult != null) { lock (_parentPerformer._asyncStateObj) { this._parentPerformer._asyncStateObj.TransactionResults.Add(sdTrResult); } } #endregion } #endregion // Set tracking phase lock (_parentPerformer._asyncStateObj.Tracking) { _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.FINISH; } }
/// <summary> /// GetCustomisations is called after GetConfiguration, /// either when a new integration is being created or when an integration is enabled. /// It is a request to the ERP system for customisation information. /// </summary> /// <returns>The ERP system responds to a GetCustomisations request, /// with a GetCustomisationsReponse, /// which contains a list of ERPCustomisations changes</returns> public ERPCustomisations GetCustomisations(NorthwindConfig nwConfig) { ERPCustomisations result; result = new ERPCustomisations(); result.Version = nwConfig.CustomisationVersion; XmlDocument resultDoc = new XmlDocument(); resultDoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?><getcustomisationsresponse/>"); AddCustomisations(ref resultDoc, "AdditionalStockDetails"); AddCustomisations(ref resultDoc, "ProductsPurchased"); AddCustomisations(ref resultDoc, "SalesInvoices"); AddCustomisations(ref resultDoc, "AccountTab"); AddCustomisations(ref resultDoc, "ErpSelections"); AddSelesReps(ref resultDoc, nwConfig); result.CustomisationData = resultDoc.DocumentElement; return result; }
private int GetNewSequenceNumber(NorthwindConfig config) { int sequenceNumber = -1; using (OleDbConnection connection = new OleDbConnection(config.ConnectionString)) { connection.Open(); sequenceNumber = GetNewSequenceNumber(config, connection); } return sequenceNumber; }
/// <summary> /// OpenSession is called at the start of every call to the ERP system. /// If OpenSession returns a token, /// then it is passed in the header for subsequent calls. /// </summary> /// <returns></returns> public SessionOpenResult OpenSession(NorthwindConfig config) { SessionOpenResult result = new SessionOpenResult(); DateTime now = DateTime.Now; string sessionExtention = "." + now.Year.ToString() + now.Month.ToString() + now.Day.ToString() + "." + now.Hour.ToString() + "." + now.Minute.ToString() + "." + now.Second.ToString() + "." + now.Millisecond.ToString(); result.SessionKey = config.LastSequenceNumber.ToString() + sessionExtention; return result; }
/// <summary> /// /// </summary> /// <param name="config"></param> /// <returns></returns> /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks> public Feed<FeedEntry> GetFeed(NorthwindConfig config, PageInfo normalizedPageInfo) { Feed<FeedEntry> syncSourceFeed; SdataContext sdataContext; SupportedResourceKinds resource; string resourceKind; string EndPoint; Guid trackingId; List<CorrelatedResSyncInfo> correlatedResSyncInfos; sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); correlatedResSyncInfos = _parentPerformer._asyncStateObj.CorrelatedResSyncInfos; EndPoint = _parentPerformer._requestContext.DatasetLink + resourceKind; trackingId = _parentPerformer._requestContext.TrackingId; //ISyncSyncDigestInfoStore syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); ISyncSyncDigestInfoStore syncDigestStore = NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); SyncDigestInfo syncDigestInfo = syncDigestStore.Get(resourceKind); // Create a new Feed instance syncSourceFeed = new Feed<FeedEntry>();//FeedComponentFactory.Create<ISyncSourceFeed>(); syncSourceFeed.Author = new FeedAuthor(); syncSourceFeed.Author.Name = "Northwind Adapter"; syncSourceFeed.Category = new FeedCategory("http://schemas.sage.com/sdata/categories", "collection", "Resource Collection"); #region Digest syncSourceFeed.Digest = new Digest(); syncSourceFeed.Digest.Entries = (syncDigestInfo == null) ? new DigestEntry[0] : new DigestEntry[syncDigestInfo.Count]; // set digest origin syncSourceFeed.Digest.Origin = _parentPerformer._requestContext.OriginEndPoint; if (syncDigestInfo != null) { // convert and set digest entries from synch store object to feed object for (int i = 0; i < syncDigestInfo.Count; i++) { syncSourceFeed.Digest.Entries[i] = new DigestEntry(); syncSourceFeed.Digest.Entries[i].ConflictPriority = syncDigestInfo[i].ConflictPriority; syncSourceFeed.Digest.Entries[i].EndPoint = syncDigestInfo[i].EndPoint; syncSourceFeed.Digest.Entries[i].Tick = (int)syncDigestInfo[i].Tick; syncSourceFeed.Digest.Entries[i].Stamp = DateTime.Now; } } #endregion #region Entries // retrieve the data connection wrapper IFeedEntryEntityWrapper wrapper = FeedEntryWrapperFactory.Create(resource, _parentPerformer._requestContext); IEnumerator<CorrelatedResSyncInfo> correlationEnumerator = PagingHelpers.GetPagedEnumerator<CorrelatedResSyncInfo>(normalizedPageInfo, correlatedResSyncInfos.ToArray()); while (correlationEnumerator.MoveNext()) { syncSourceFeed.Entries.Add(this.BuildFeedEntry(correlationEnumerator.Current, wrapper)); } #endregion // initialize the feed string feedUrl = string.Format("{0}/$syncSource('{1}')", EndPoint, trackingId); string feedUrlWithoutQuery = (new Uri(feedUrl)).GetLeftPart(UriPartial.Path); // the url without query // set id tag syncSourceFeed.Id = feedUrl; // set title tag syncSourceFeed.Title = string.Format("{0} synchronization source feed {1}", resourceKind.ToString(), trackingId); // set update // syncSourceFeed.Updated = DateTime.Now; // set syncMode syncSourceFeed.SyncMode = SyncMode.catchUp;// syncModeenum.catchUp; // add links (general) syncSourceFeed.Links.AddRange(LinkFactory.CreateFeedLinks(_parentPerformer._requestContext, feedUrl)); #region PAGING & OPENSEARCH // add links (paging) syncSourceFeed.Links.AddRange(LinkFactory.CreatePagingLinks(normalizedPageInfo, correlatedResSyncInfos.Count, feedUrlWithoutQuery)); /* OPENSEARCH */ syncSourceFeed.ItemsPerPage = normalizedPageInfo.Count; syncSourceFeed.StartIndex = normalizedPageInfo.StartIndex; syncSourceFeed.TotalResults = correlatedResSyncInfos.Count; #endregion return syncSourceFeed; }
private void AddSelesReps(ref XmlDocument resultDoc, NorthwindConfig nwConfig) { try { // declarations string sqlQuery; OleDbDataAdapter dataAdapter; int nOfRows; DataSet dataSet; XmlElement addcustomcaptions; XmlElement subElem; string name; string id; int maxSalesCode = 0; // initializations dataSet = null; nOfRows = 0; dataSet = new DataSet(); sqlQuery = @"SELECT Employees.EmployeeID, Employees.FirstName + ' ' + Employees.LastName as Name FROM Employees"; // get the data base records using a table adapter. using (OleDbConnection connection = new OleDbConnection(nwConfig.ConnectionString)) { connection.Open(); dataAdapter = new OleDbDataAdapter(sqlQuery, connection); dataAdapter.Fill(dataSet, "Employees"); OleDbCommand Cmd = new OleDbCommand("SELECT Max(Employees.EmployeeID) AS MaxOfID FROM Employees", connection); object lastid = Cmd.ExecuteScalar(); maxSalesCode = (int)lastid; } for (int index = 1; index <= maxSalesCode; index++) { addcustomcaptions = resultDoc.CreateElement("deletecustomcaption"); subElem = resultDoc.CreateElement("familytype"); subElem.InnerText = "Choices"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("family"); subElem.InnerText = "salesrepresentative"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("code"); subElem.InnerText = index.ToString(); addcustomcaptions.AppendChild(subElem); resultDoc.DocumentElement.AppendChild(addcustomcaptions); } foreach (DataRow row in dataSet.Tables[0].Rows) { if (row.IsNull(0) || row.IsNull(1)) continue; id = row[0].ToString(); name = row[1].ToString(); addcustomcaptions = resultDoc.CreateElement("addcustomcaptions"); subElem = resultDoc.CreateElement("familytype"); subElem.InnerText = "Choices"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("family"); subElem.InnerText = "salesrepresentative"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("code"); subElem.InnerText = id; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("order"); subElem.InnerText = id; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("de"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("es"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("fr"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("uk"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("us"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); resultDoc.DocumentElement.AppendChild(addcustomcaptions); } } catch (Exception) { } }
private SalesOrderFeedEntry GetPayload(Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.CalculatedOrdersRow row, Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.CalculatedOrderDetailsDataTable detailDataTable, NorthwindConfig config) { #region Declarations SalesOrderFeedEntry payload; string id; CountryCodes countryCodes = new CountryCodes(); #endregion id = row.OrderID.ToString(); payload = new SalesOrderFeedEntry(); payload.UUID = GetUuid(id, "", SupportedResourceKinds.salesOrders); payload.active = true; payload.currency = config.CurrencyCode; payload.pricelist = new PriceListFeedEntry(); payload.pricelist.UUID = GetUuid(id, "", SupportedResourceKinds.priceLists); if (!row.IsCustomerIDNull()) { /*payload.tradingAccount = new TradingAccountFeedEntry(); payload.tradingAccount.Key = Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix + row.CustomerID; payload.tradingAccount.UUID = GetUuid(payload.tradingAccount.Key, "", SupportedResourceKinds.tradingAccounts); payload.tradingAccount.Id = GetSDataId(payload.tradingAccount.Key, SupportedResourceKinds.tradingAccounts); payload.tradingAccount.Uri = payload.tradingAccount.Id;*/ payload.tradingAccount = (TradingAccountFeedEntry)_tradingAccountsFeedEntryWrapper.GetFeedEntry(Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix + row.CustomerID); } if (!row.IsOrderDateNull()) { payload.date = row.OrderDate; } //payload.lineCount = detailDataTable.Rows.Count; payload.discountTotal = row.IsDiscountAmountNull() ? new decimal(0) : Convert.ToDecimal(row.DiscountAmount); payload.netTotal = row.IsTotalNetPriceNull() ? new decimal(0) : Convert.ToDecimal(row.TotalNetPrice); payload.carrierTotalPrice = row.IsFreightNull() ? new decimal(0) : row.Freight; payload.grossTotal = payload.netTotal; if (!row.IsRequiredDateNull()) { payload.dueDate = row.RequiredDate; } if (!row.IsShipViaNull()) { payload.deliveryMethod = row.ShipVia.ToString(); ; } PostalAddressFeedEntry address = new PostalAddressFeedEntry(); address.active = true; address.address1 = row.IsShipAddressNull() ? null : row.ShipAddress; address.country = row.IsShipCountryNull() ? null : row.ShipCountry; address.townCity = row.IsShipCityNull() ? null : row.ShipCity; address.zipPostCode = row.IsShipPostalCodeNull() ? null : row.ShipPostalCode; address.type = postalAddressTypeenum.Shipping; payload.postalAddresses = new PostalAddressFeed(); //TODO: check if valid Address? payload.postalAddresses.Entries.Add(address); payload.salesOrderLines = new SalesOrderLineFeed(); foreach (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.CalculatedOrderDetailsRow detailRow in detailDataTable.Rows) { SalesOrderLineFeedEntry soPayload = GetLineItem(detailRow, config); payload.salesOrderLines.Entries.Add(soPayload); } return payload; }
/// <summary> /// /// </summary> /// <param name="config"></param> /// <returns></returns> /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks> public Feed<FeedEntry> GetFeed(NorthwindConfig config, PageInfo normalizedPageInfo) { Feed<FeedEntry> syncTargetFeed = new Feed<FeedEntry>(); syncTargetFeed.Author = new FeedAuthor(); syncTargetFeed.Author.Name = "Northwind Adapter"; syncTargetFeed.Category = new FeedCategory("http://schemas.sage.com/sdata/categories", "collection", "Resource Collection"); SdataContext sdataContext; SupportedResourceKinds resource; string resourceKind; string EndPoint; Guid trackingId; List<SdataTransactionResult> transactinResults; sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); transactinResults = _parentPerformer._asyncStateObj.TransactionResults; EndPoint = _parentPerformer._requestContext.DatasetLink + resourceKind; ; trackingId = _parentPerformer._requestContext.TrackingId; // Create a new Feed instance // retrieve the data connection wrapper IFeedEntryEntityWrapper wrapper = FeedEntryWrapperFactory.Create(resource, _parentPerformer._requestContext); IEnumerator<SdataTransactionResult> transactionResultEnumerator = PagingHelpers.GetPagedEnumerator<SdataTransactionResult>(normalizedPageInfo, transactinResults.ToArray()); while (transactionResultEnumerator.MoveNext()) { syncTargetFeed.Entries.Add(this.BuildFeedEntry(transactionResultEnumerator.Current, wrapper)); } // initialize the feed string feedUrl = string.Format("{0}/$syncTarget('{1}')", EndPoint, trackingId); string feedUrlWithoutQuery = (new Uri(feedUrl)).GetLeftPart(UriPartial.Path); // the url without query // set id tag syncTargetFeed.Id = feedUrl; // set title tag syncTargetFeed.Title = string.Format("{0} synchronization target feed {1}", resourceKind.ToString(), trackingId); // set update #warning implement this //syncTargetFeed.Updated = DateTime.Now; // set syncMode syncTargetFeed.SyncMode = SyncMode.catchUp; // add links (general) syncTargetFeed.Links.AddRange(LinkFactory.CreateFeedLinks(_parentPerformer._requestContext, feedUrl)); #region PAGING & OPENSEARCH // add links (paging) syncTargetFeed.Links.AddRange(LinkFactory.CreatePagingLinks(normalizedPageInfo, transactinResults.Count, feedUrlWithoutQuery)); /* OPENSEARCH */ syncTargetFeed.ItemsPerPage = normalizedPageInfo.Count; syncTargetFeed.StartIndex = normalizedPageInfo.StartIndex; syncTargetFeed.TotalResults = transactinResults.Count; #endregion return syncTargetFeed; }
private SalesOrderPayload GetPayload(DataSets.Order.CalculatedOrdersRow row, DataSets.Order.CalculatedOrderDetailsDataTable detailDataTable, //DataSets.Order.DeletedOrderDetailsDataTable deletedOrderDetailsDataTable, NorthwindConfig config) { #region Declarations SalesOrderPayload payload; string id; CountryCodes countryCodes = new CountryCodes(); #endregion id = row.OrderID.ToString(); payload = new SalesOrderPayload(); payload.LocalID = id; payload.SyncUuid = GetUuid(id, "", SupportedResourceKinds.salesOrders); payload.SalesOrdertype.active = true; payload.SalesOrdertype.applicationID = id; payload.SalesOrdertype.currency = config.CurrencyCode; payload.ForeignIds.Add("pricelist", Sage.Integration.Northwind.Application.API.Constants.DefaultValues.PriceList.ID); if (!row.IsCustomerIDNull()) payload.ForeignIds.Add("tradingAccount", Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix + row.CustomerID); if (!row.IsOrderDateNull()) { payload.SalesOrdertype.date = row.OrderDate; payload.SalesOrdertype.dateSpecified = true; } payload.SalesOrdertype.lineCountSpecified = true; payload.SalesOrdertype.lineCount = detailDataTable.Rows.Count; payload.SalesOrdertype.discountTotalSpecified = true; payload.SalesOrdertype.discountTotal = row.IsDiscountAmountNull() ? new decimal(0) : Convert.ToDecimal(row.DiscountAmount); payload.SalesOrdertype.netTotalSpecified = true; payload.SalesOrdertype.netTotal = row.IsTotalNetPriceNull() ? new decimal(0) : Convert.ToDecimal(row.TotalNetPrice); payload.SalesOrdertype.carrierTotalPriceSpecified = true; payload.SalesOrdertype.carrierTotalPrice = row.IsFreightNull() ? new decimal(0) : row.Freight; payload.SalesOrdertype.grossTotalSpecified = true; payload.SalesOrdertype.grossTotal = payload.SalesOrdertype.netTotal; if (!row.IsRequiredDateNull()) { payload.SalesOrdertype.dueDateSpecified = true; payload.SalesOrdertype.dueDate = row.RequiredDate; } if (!row.IsShipViaNull()) { payload.SalesOrdertype.deliveryMethod = row.ShipVia.ToString(); ; } postalAddresstype address = new postalAddresstype(); address.active = true; address.activeSpecified = true; address.address1 = row.IsShipAddressNull() ? "" : row.ShipAddress; address.applicationID = id; address.country = row.IsShipCountryNull() ? "" : row.ShipCountry; address.townCity = row.IsShipCityNull() ? "" : row.ShipCity; address.zipPostCode = row.IsShipPostalCodeNull() ? "" : row.ShipPostalCode; address.type = postalAddressTypeenum.Shipping; payload.SalesOrdertype.postalAddresses = new postalAddresstype[1]; payload.SalesOrdertype.postalAddresses[0] = address; payload.SalesOrdertype.salesOrderLines = new salesOrderLinetype[detailDataTable.Rows.Count]; int index = 0; foreach (DataSets.Order.CalculatedOrderDetailsRow detailRow in detailDataTable.Rows) { SalesOrderLinePayload soPayload = GetLineItem(detailRow, config); payload.ForeignIds.Add( String.Format("salesOrderLines[{0}]", index.ToString()), soPayload.LocalID); foreach (string key in soPayload.ForeignIds.Keys)// (int foreignIdIndex = 0; foreignIdIndex <= soPayload.ForeignIds.Count; foreignIdIndex++) { string value; if (soPayload.ForeignIds.TryGetValue(key, out value)) { payload.ForeignIds.Add( String.Format("salesOrderLines[{0}]/{1}", index.ToString(), key), value); } } payload.SalesOrdertype.salesOrderLines[index] = soPayload.SalesOrderLinetype; index++; } //foreach (DataSets.Order.DeletedOrderDetailsRow deletedRow in deletedOrderDetailsDataTable.Rows) //{ // lineItemDoc = new LineItemDocument(); // lineItemDoc.Id = deletedRow[0].ToString(); // lineItemDoc.LogState = LogState.Deleted; // doc.orderitems.Add(lineItemDoc); //} return payload; }
public RequestContext(SDataUri sdataUri) { this.SdataUri = sdataUri; // config NorthwindConfig newConfig = new NorthwindConfig(sdataUri.CompanyDataset); newConfig.CurrencyCode = "EUR"; newConfig.CrmUser = "******"; newConfig.Path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Northwind"); this.Config = newConfig; // initialize requestType this.RequestType = RequestType.None; // hasTrackingId this.HasTrackingId = false; // baseLink string newBaseLink = string.Empty; if (String.IsNullOrEmpty(sdataUri.Scheme)) newBaseLink += "http://"; else newBaseLink += sdataUri.Scheme + "://"; if (String.IsNullOrEmpty(sdataUri.Host)) newBaseLink += "localhost"; else newBaseLink += sdataUri.Host; if (sdataUri.Port > 0) newBaseLink += ":" + sdataUri.Port.ToString(); if (String.IsNullOrEmpty(sdataUri.Server)) newBaseLink += "/sdata/"; else newBaseLink += "/" + sdataUri.Server + "/"; this.BaseLink = newBaseLink; // application this.Application = (sdataUri.PathSegments.Length > 0) ? sdataUri.PathSegments[0].Text : ""; // applicationLink this.ApplicationLink = this.BaseLink + this.Application + "/"; if (sdataUri.PathSegments.Length == 1) { this.RequestType = RequestType.Contract; // -> Type: contract return; } // contract string newContract = sdataUri.PathSegments[1].Text; if (newContract == "*") { this.RequestType = RequestType.Contract; // -> Type: contract this.Contract = string.Empty; return; } this.Contract = newContract; // contractLink this.ContractLink = this.ApplicationLink + this.Contract + "/"; if (sdataUri.PathSegments.Length == 2) { this.RequestType = RequestType.Dataset; // -> Type: dataset return; } // dataset string newDataset = sdataUri.PathSegments[2].Text; if (newDataset == "*") { this.RequestType = RequestType.Dataset; // -> Type: dataset this.Dataset = string.Empty; return; } this.Dataset = newDataset; // datasetLink this.DatasetLink = this.ContractLink + this.Dataset + "/"; // sdataContext this.SdataContext = new SdataContext(this.Application, this.Dataset, this.Contract, this.DatasetLink); if (this.SdataUri.PathSegments.Length == 3) { if (!string.IsNullOrEmpty(this.SdataUri.ServiceMethod)) { this.RequestType = RequestType.Service; // -> Type: Service return; } this.RequestType = RequestType.ResourceCollection; // -> Type: ResourceCollection return; } string temp; temp = this.SdataUri.PathSegments[3].Text; if (temp == "*") { this.RequestType = RequestType.ResourceCollection; // -> Type: ResourceCollection return; } if (temp.Equals(Constants.schema, StringComparison.InvariantCultureIgnoreCase)) { // check whether it is an import schema if (this.SdataUri.PathSegments.Length == 4) { this.RequestType = RequestType.ResourceCollectionSchema; // -> Type: ResourceCollectionSchema return; } else if (this.SdataUri.PathSegments.Length == 6 && this.SdataUri.PathSegments[4].Text.Equals("import", StringComparison.InvariantCultureIgnoreCase) && (!string.IsNullOrEmpty(this.SdataUri.PathSegments[5].Text))) { this.ImportSchemaName = this.SdataUri.PathSegments[5].Text; this.RequestType = RequestType.ImportSchema; // -> Type: ImportSchema return; } } if (temp.Equals(Constants.service, StringComparison.InvariantCultureIgnoreCase)) { if (this.SdataUri.PathSegments.Length >= 6) { this.SdataUri.ServiceMethod = this.SdataUri.PathSegments[4].Text; if (this.SdataUri.PathSegments[5].Text.Equals(Constants.schema, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.ServiceSchema; return; } } else { throw new RequestException(string.Format("Url {0} cannot be parsed.", this.SdataUri.ToString())); } } try { // resourceKind this.ResourceKind = (SupportedResourceKinds)Enum.Parse(typeof(SupportedResourceKinds), temp, true); if (sdataUri.PathSegments.Length > 4 && sdataUri.PathSegments[4].Text.Equals(Constants.linked, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.Linked; // -> Type: Linked // resourceKey if (sdataUri.PathSegments[4].HasPredicate) { if (sdataUri.PathSegments[4].PredicateExpression is StringLiteralExpression) { this.ResourceKey = ((StringLiteralExpression)sdataUri.PathSegments[4].PredicateExpression).Value.ToString(); return; } else { this.RequestType = RequestType.None; // -> Type: None this.ResourceKind = SupportedResourceKinds.None; this.ErrorMessage = "please specify the primary Key inside the predicate as string"; return; } } } else if (!string.IsNullOrEmpty(this.SdataUri.ServiceMethod)) { if (sdataUri.PathSegments.Length >= 7 && sdataUri.PathSegments[6].Text.Equals(Constants.schema, StringComparison.InvariantCultureIgnoreCase)) this.RequestType = RequestType.ServiceSchema; // currently we do not enter here, but we don't know if SIF will be changed to set the service name else this.RequestType = RequestType.Service; // -> Type: Service return; } else if (sdataUri.PathSegments.Length >= 7 && sdataUri.PathSegments[4].Text.Equals(Constants.service, StringComparison.InvariantCultureIgnoreCase) && sdataUri.PathSegments[6].Text.Equals(Constants.schema, StringComparison.InvariantCultureIgnoreCase)) { this.SdataUri.ServiceMethod = sdataUri.PathSegments[5].Text; this.RequestType = RequestType.ServiceSchema; return; } else { this.RequestType = RequestType.Resource; // -> Type. Resource // resourceKey if (sdataUri.PathSegments[3].HasPredicate) { if (sdataUri.PathSegments[3].PredicateExpression is StringLiteralExpression) { this.ResourceKey = ((StringLiteralExpression)sdataUri.PathSegments[3].PredicateExpression).Value.ToString(); return; } else { this.RequestType = RequestType.None; // -> Type: None this.ResourceKind = SupportedResourceKinds.None; this.ErrorMessage = "please specify the primary Key inside the predicate as string"; return; } } } } catch (Exception e) { this.RequestType = RequestType.None; this.ResourceKind = SupportedResourceKinds.None; this.ErrorMessage = e.Message; return; } if (this.SdataUri.PathSegments.Length == 4) return; temp = sdataUri.PathSegments[4].Text; if (temp.Equals(Constants.schema, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.ResourceSchema; // -> Type: ResourceSchema return; } if (temp.Equals(Constants.template, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.Template; // -> Type: template return; } if (temp.Equals(Constants.syncDigest, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.SyncDigest; // -> Type: syncDigest return; } if (temp.Equals(Constants.syncResults, StringComparison.InvariantCultureIgnoreCase)) { this.RequestType = RequestType.SyncResults; // -> Type: SyncResults return; } if ((temp.Equals(Constants.syncSource, StringComparison.InvariantCultureIgnoreCase)) || (temp.Equals(Constants.syncTarget, StringComparison.InvariantCultureIgnoreCase))) { if (temp.Equals(Constants.syncSource, StringComparison.InvariantCultureIgnoreCase)) this.RequestType = RequestType.SyncSource; // -> Type: syncSource if (temp.Equals(Constants.syncTarget, StringComparison.InvariantCultureIgnoreCase)) this.RequestType = RequestType.SyncTarget; // -> Type: syncTarget if (!string.IsNullOrEmpty(sdataUri.TrackingID)) { try { GuidConverter converter = new GuidConverter(); this.TrackingId = (Guid)converter.ConvertFrom(sdataUri.TrackingID); this.HasTrackingId = true; } catch (Exception) { } } else if (this.SdataUri.PathSegments[4].HasPredicate) { try { GuidConverter converter = new GuidConverter(); this.TrackingId = (Guid)converter.ConvertFrom(((StringLiteralExpression)this.SdataUri.PathSegments[4].PredicateExpression).Value); this.HasTrackingId = true; } catch (Exception) { } } return; } }
private void AddSelesReps(ref XmlDocument resultDoc, NorthwindConfig nwConfig) { try { // declarations string sqlQuery; OleDbDataAdapter dataAdapter; int nOfRows; DataSet dataSet; XmlElement addcustomcaptions; XmlElement subElem; string name; string id; int maxSalesCode = 0; // initializations dataSet = null; nOfRows = 0; dataSet = new DataSet(); sqlQuery = @"SELECT Employees.EmployeeID, Employees.FirstName + ' ' + Employees.LastName as Name FROM Employees"; // get the data base records using a table adapter. using (OleDbConnection connection = new OleDbConnection(nwConfig.ConnectionString)) { connection.Open(); dataAdapter = new OleDbDataAdapter(sqlQuery, connection); dataAdapter.Fill(dataSet, "Employees"); OleDbCommand Cmd = new OleDbCommand("SELECT Max(Employees.EmployeeID) AS MaxOfID FROM Employees", connection); object lastid = Cmd.ExecuteScalar(); maxSalesCode = (int)lastid; } for (int index = 1; index <= maxSalesCode; index++) { addcustomcaptions = resultDoc.CreateElement("deletecustomcaption"); subElem = resultDoc.CreateElement("familytype"); subElem.InnerText = "Choices"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("family"); subElem.InnerText = "salesrepresentative"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("code"); subElem.InnerText = index.ToString(); addcustomcaptions.AppendChild(subElem); resultDoc.DocumentElement.AppendChild(addcustomcaptions); } foreach (DataRow row in dataSet.Tables[0].Rows) { if (row.IsNull(0) || row.IsNull(1)) { continue; } id = row[0].ToString(); name = row[1].ToString(); addcustomcaptions = resultDoc.CreateElement("addcustomcaptions"); subElem = resultDoc.CreateElement("familytype"); subElem.InnerText = "Choices"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("family"); subElem.InnerText = "salesrepresentative"; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("code"); subElem.InnerText = id; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("order"); subElem.InnerText = id; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("de"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("es"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("fr"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("uk"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); subElem = resultDoc.CreateElement("us"); subElem.InnerText = name; addcustomcaptions.AppendChild(subElem); resultDoc.DocumentElement.AppendChild(addcustomcaptions); } } catch (Exception) { } }
/// <summary> /// /// </summary> /// <param name="config"></param> /// <returns></returns> /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks> public SyncFeed GetFeed(NorthwindConfig config, int startIndex, int count) { SyncFeed feed; SdataContext sdataContext; SupportedResourceKinds resource; string resourceKind; string endpoint; Guid trackingId; List<SdataTransactionResult> transactinResults; sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); transactinResults = _parentPerformer._asyncStateObj.TransactionResults; endpoint = _parentPerformer._requestContext.DatasetLink + resourceKind; ; trackingId = _parentPerformer._requestContext.TrackingId; if (count == 0) count = 10; feed = new SyncFeed(); Token emptyToken = new Token(); IEntityWrapper wrapper = EntityWrapperFactory.Create(resource, _parentPerformer._requestContext); for (int index = startIndex; index < ((startIndex + count > transactinResults.Count) ? transactinResults.Count : startIndex + count); index++) { SdataTransactionResult transactionResult = (SdataTransactionResult)transactinResults[index]; SyncFeedEntry entry = wrapper.GetFeedEntry(transactionResult); if (entry != null) feed.Entries.Add(entry); else { entry = new SyncFeedEntry(); entry.Uuid = transactionResult.Uuid; entry.HttpStatusCode = transactionResult.HttpStatus; entry.HttpMessage = transactionResult.HttpMessage; ; entry.HttpMethod = transactionResult.HttpMethod; entry.HttpLocation = transactionResult.Location; entry.HttpETag = transactionResult.Etag; feed.Entries.Add(entry); } } // initialize the feed string url = string.Format("{0}/$syncTarget('{1}')", endpoint, trackingId); feed.Title = resourceKind; feed.Id = url; #region PAGING & OPENSEARCH int totalResults = transactinResults.Count; PageController pageController = new PageController(startIndex+1, FeedMetadataHelpers.DEFAULT_ITEMS_PER_PAGE, totalResults, count, url); /* PAGING */ FeedLinkCollection feedLinks = new FeedLinkCollection(); feedLinks.Add(new FeedLink(pageController.GetLinkSelf(), LinkType.Self, MediaType.Atom, "Current Page")); feedLinks.Add(new FeedLink(pageController.GetLinkFirst(), LinkType.First, MediaType.Atom, "First Page")); feedLinks.Add(new FeedLink(pageController.GetLinkLast(), LinkType.Last, MediaType.Atom, "Last Page")); string linkUrl; if (pageController.GetLinkNext(out linkUrl)) feedLinks.Add(new FeedLink(linkUrl, LinkType.Next, MediaType.Atom, "Next Page")); if (pageController.GetLinkPrevious(out linkUrl)) feedLinks.Add(new FeedLink(linkUrl, LinkType.Previous, MediaType.Atom, "Previous Page")); feed.Links = feedLinks; /* OPENSEARCH */ feed.Opensearch_ItemsPerPageElement = pageController.GetOpensearch_ItemsPerPageElement(); feed.Opensearch_StartIndexElement = pageController.GetOpensearch_StartIndexElement(); feed.Opensearch_TotalResultsElement = pageController.GetOpensearch_TotalResultsElement(); #endregion //if (startIndex + count < transactinResults.Count) //{ // FeedLink linkNext = new FeedLink(string.Format("{0}?startIndex={1}&count=10", url, startIndex + count), LinkType.Next); // feed.Links.Add(linkNext); //} //FeedLink linkFirst = new FeedLink(String.Format("{0}?startIndex=0&count=10", url), LinkType.First); //feed.Links.Add(linkFirst); //FeedLink linkSelf = new FeedLink(String.Format("{0}?startIndex={1}&count=10", url, startIndex), LinkType.Self); //feed.Links.Add(linkSelf); return feed; }
/// <summary> /// /// </summary> /// <param name="config"></param> /// <returns></returns> /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks> public SyncFeed GetFeed(NorthwindConfig config, int startIndex, int count) { SyncFeed feed; SdataContext sdataContext; SupportedResourceKinds resource; string resourceKind; string endpoint; Guid trackingId; List<CorrelatedResSyncInfo> correlatedResSyncInfos; sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); correlatedResSyncInfos = _parentPerformer._asyncStateObj.CorrelatedResSyncInfos; endpoint = _parentPerformer._requestContext.DatasetLink + resourceKind; trackingId = _parentPerformer._requestContext.TrackingId; ISyncSyncDigestInfoStore syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); SyncDigestInfo syncDigestInfo = syncDigestStore.Get(resourceKind); if (count == 0) count = 10; feed = new SyncFeed(); Token emptyToken = new Token(); feed.Digest = new SyncFeedDigest(); feed.Digest.Origin = _parentPerformer._requestContext.OriginEndPoint; feed.Digest.Entries = new List<SyncFeedDigestEntry>(); if (syncDigestInfo != null) { foreach (SyncDigestEntryInfo entryinfo in syncDigestInfo) { SyncFeedDigestEntry entry = new SyncFeedDigestEntry(); entry.ConflictPriority = entryinfo.ConflictPriority; entry.Endpoint = entryinfo.Endpoint; entry.Tick = entryinfo.Tick; entry.Stamp = DateTime.Now; feed.Digest.Entries.Add(entry); } } IEntityWrapper wrapper = EntityWrapperFactory.Create(resource, _parentPerformer._requestContext); for (int index = startIndex; index < ((startIndex + count > correlatedResSyncInfos.Count) ? correlatedResSyncInfos.Count : startIndex + count); index++) { CorrelatedResSyncInfo resSyncInfo = (CorrelatedResSyncInfo)correlatedResSyncInfos[index]; SyncFeedEntry entry = wrapper.GetFeedEntry(resSyncInfo); if (entry != null) feed.Entries.Add(entry); else { entry = new SyncFeedEntry(); entry.HttpMethod = "DELETE"; entry.Uuid = resSyncInfo.ResSyncInfo.Uuid; feed.Entries.Add(entry); } } // initialize the feed string url = string.Format("{0}/$syncSource('{1}')", endpoint, trackingId); feed.Id = url; feed.Title = resourceKind; #region PAGING & OPENSEARCH int totalResults = correlatedResSyncInfos.Count; PageController pageController = new PageController(startIndex+1, FeedMetadataHelpers.DEFAULT_ITEMS_PER_PAGE, totalResults, count, url); /* PAGING */ FeedLinkCollection feedLinks = new FeedLinkCollection(); feedLinks.Add(new FeedLink(pageController.GetLinkSelf(), LinkType.Self, MediaType.Atom, "Current Page")); feedLinks.Add(new FeedLink(pageController.GetLinkFirst(), LinkType.First, MediaType.Atom, "First Page")); feedLinks.Add(new FeedLink(pageController.GetLinkLast(), LinkType.Last, MediaType.Atom, "Last Page")); string linkUrl; if (pageController.GetLinkNext(out linkUrl)) feedLinks.Add(new FeedLink(linkUrl, LinkType.Next, MediaType.Atom, "Next Page")); if (pageController.GetLinkPrevious(out linkUrl)) feedLinks.Add(new FeedLink(linkUrl, LinkType.Previous, MediaType.Atom, "Previous Page")); feed.Links = feedLinks; /* OPENSEARCH */ feed.Opensearch_ItemsPerPageElement = pageController.GetOpensearch_ItemsPerPageElement(); feed.Opensearch_StartIndexElement = pageController.GetOpensearch_StartIndexElement(); feed.Opensearch_TotalResultsElement = pageController.GetOpensearch_TotalResultsElement(); #endregion //feed.Id = url; //if (startIndex + count < correlatedResSyncInfos.Count) //{ // FeedLink linkNext = new FeedLink(string.Format("{0}?startIndex={1}&count=10", url, startIndex + count), LinkType.Next); // feed.Links.Add(linkNext); //} //FeedLink linkFirst = new FeedLink(String.Format("{0}?startIndex=0&count=10", url), LinkType.First); //feed.Links.Add(linkFirst); //FeedLink linkSelf = new FeedLink(String.Format("{0}?startIndex={1}&count=10", url, startIndex), LinkType.Self); //feed.Links.Add(linkSelf); return feed; }
private int GetLastSequenceNumber(NorthwindConfig config, OleDbConnection connection) { int sequenceNumber = -1; OleDbCommand Cmd = new OleDbCommand("SELECT Max(Sequence.ID) AS MaxOfID FROM Sequence", connection); object lastid = Cmd.ExecuteScalar(); if (lastid == null || lastid == DBNull.Value) sequenceNumber = 0; else sequenceNumber = (int)lastid; return sequenceNumber; }
// Asynchronous called method private void Execute(NorthwindConfig config, SyncFeedDigest syncDigestInfo) { #region Declaration SdataContext sdataContext; SupportedResourceKinds resource; IAppBookmarkInfoStore appBookmarkInfoStore; ICorrelatedResSyncInfoStore correlatedResSyncInfoStore; ISyncSyncDigestInfoStore syncDigestStore; ISyncTickProvider tickProvider; string resourceKind; string endpoint; int nextTick = 0; Token lastToken; Token nextToken; Identity[] changedIdentites; IEntityWrapper wrapper; #endregion #region init sdataContext = _parentPerformer._requestContext.SdataContext; resource = _parentPerformer._requestContext.ResourceKind; resourceKind = resource.ToString(); endpoint = _parentPerformer._requestContext.DatasetLink + resourceKind; appBookmarkInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetAppBookmarkStore(sdataContext); correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(sdataContext); syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext); tickProvider = RequestReceiver.NorthwindAdapter.StoreLocator.GetTickProvider(sdataContext); wrapper = EntityWrapperFactory.Create(resource, _parentPerformer._requestContext); #endregion #region get last token or create a new one if (!appBookmarkInfoStore.Get<Token>(resourceKind, out lastToken)) { lastToken = new Token(); lastToken.InitRequest = true; } #endregion #region Get local identities of changed entries since last synchronisation changedIdentites = wrapper.Entity.GetLastChanges(lastToken, config, out nextToken); #endregion if (resource == SupportedResourceKinds.phoneNumbers) { #region workaround for phones for (int index = 0; index < changedIdentites.Length; index++) { string phoneid = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix; string faxId = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix; // receive the feed entry for local identity SyncFeedEntry phoneentry = wrapper.GetFeedEntry(phoneid); SyncFeedEntry faxentry = wrapper.GetFeedEntry(faxId); if (phoneentry == null && faxentry == null) continue; // receive the correlation for the local identity if (phoneentry != null) { CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { phoneid }); string etag = EtagServices.ComputeEtag(phoneentry.Payload, true); // new etag if (correlatedResSyncInfos.Length == 0) { nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(phoneid, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nextTick = tickProvider.CreateNextTick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick; correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } if (faxentry != null) { CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { faxId }); string etag = EtagServices.ComputeEtag(faxentry.Payload, true); // new etag if (correlatedResSyncInfos.Length == 0) { nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(faxId, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nextTick = tickProvider.CreateNextTick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick; correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } } #endregion } else { for (int index = 0; index < changedIdentites.Length; index++) { string id = changedIdentites[index].Id; // receive the feed entry for local identity SyncFeedEntry entry = wrapper.GetFeedEntry(id); if (entry == null) continue; // receive the correlation for the local identity CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { id }); string etag = EtagServices.ComputeEtag(entry.Payload, true); // new etag if (correlatedResSyncInfos.Length == 0) { nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now); CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(id, resyncInfo); correlatedResSyncInfoStore.Put(resourceKind, info); syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo); } else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag)) { nextTick = tickProvider.CreateNextTick(resourceKind); correlatedResSyncInfos[0].ResSyncInfo.Etag = etag; correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick; correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint; correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now; correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]); syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo); } } } #region store next token appBookmarkInfoStore.Put(resourceKind, nextToken); #endregion // set tracking phase lock (_parentPerformer._asyncStateObj) { _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.GETCHANGESBYTICK; } // Receive syncDigestInfo if (null != syncDigestInfo) { ICorrelatedResSyncInfoEnumerator enumerator; List<string> endpoints = new List<string>(); foreach (SyncFeedDigestEntry digestEntry in syncDigestInfo.Entries) { endpoints.Add(digestEntry.Endpoint); enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, digestEntry.Endpoint, digestEntry.Tick-2); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } SyncDigestInfo sourceSyncDigestInfo = syncDigestStore.Get(resourceKind); foreach (SyncDigestEntryInfo digestEntry in sourceSyncDigestInfo) { if (endpoints.Contains(digestEntry.Endpoint)) continue; endpoints.Add(digestEntry.Endpoint); enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, digestEntry.Endpoint, -1); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } if (!endpoints.Contains(endpoint)) { enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, endpoint, -1); while (enumerator.MoveNext()) { // No lock needed, as we expect that CorrelatedResSyncInfos list is // only acceeded anywhere else when Tracking phase is 'finish'. //lock(_parentPerformer._asyncStateObj) //{ _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current); //} } } } // Set tracking phase lock (_parentPerformer._asyncStateObj.Tracking) { _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.FINISH; } }
private int GetNewSequenceNumber(NorthwindConfig config, OleDbConnection connection) { //Sequence sequence; //sequence = new Data.Sequence(); int sequenceNumber = -1; //SequenceTableAdapter sequenceTableAdapter; //sequenceTableAdapter = new SequenceTableAdapter(); //Sequence.SequenceRow row = sequence._Sequence.NewSequenceRow(); //row.Date = DateTime.Now; //sequence._Sequence.AddSequenceRow(row); //sequenceTableAdapter.Connection = connection; //sequenceTableAdapter.Update(sequence._Sequence); OleDbCommand CmdSequence = new OleDbCommand("INSERT INTO Sequence ( [Date] ) SELECT Now()", connection); CmdSequence.ExecuteNonQuery(); OleDbCommand Cmd = new OleDbCommand("SELECT @@IDENTITY", connection); object lastid = Cmd.ExecuteScalar(); sequenceNumber = (int)lastid; return sequenceNumber; }
private SalesOrderLineFeedEntry GetLineItem(Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.CalculatedOrderDetailsRow row, NorthwindConfig config) { #region Declarations SalesOrderLineFeedEntry payload; string id; decimal discountPercentage; #endregion id = row.OrderID.ToString() + "-" + row.ProductID.ToString(); payload = new SalesOrderLineFeedEntry(); payload.UUID = GetUuid(id, "", SupportedResourceKinds.salesOrderLines); payload.commodity = (CommodityFeedEntry)_commoditiesFeedEntryWrapper.GetFeedEntry(row.ProductID.ToString()); /* payload.commodity = new CommodityFeedEntry(); payload.commodity.UUID = GetUuid(row.ProductID.ToString(), "", SupportedResourceKinds.commodities);*/ payload.salesOrder = new SalesOrderFeedEntry(); payload.salesOrder.UUID = GetUuid(row.OrderID.ToString(), "", SupportedResourceKinds.salesOrders); payload.unitOfMeasure = (UnitOfMeasureFeedEntry)_unitsOfMeasureFeedEntryWrapper.GetFeedEntry(row.ProductID.ToString()); /*payload.unitOfMeasure = new UnitOfMeasureFeedEntry(); payload.unitOfMeasure.UUID = GetUuid(row.ProductID.ToString(), "", SupportedResourceKinds.unitsOfMeasure);*/ payload.quantity = row.IsQuantityNull() ? Convert.ToInt16(0) : row.Quantity; payload.initialPrice = row.IsUnitPriceNull() ? new decimal(0) : row.UnitPrice; payload.orderLineDiscountPercent = row.IsDiscountNull() ? (decimal)0 : Convert.ToDecimal(row.Discount); payload.discountTotal = payload.initialPrice * (decimal)payload.orderLineDiscountPercent; payload.costTotal = (decimal)payload.initialPrice * (1 - payload.orderLineDiscountPercent); payload.netTotal = Convert.ToDecimal(payload.quantity) * Convert.ToDecimal(payload.costTotal); SetCommonProperties(id, payload, SupportedResourceKinds.salesOrderLines); return payload; }