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;
        }
Esempio n. 3
0
 public Pricing CheckPrice(Pricing PricingInformation, NorthwindConfig northwindConfig)
 {
     Pricing result;
     Product product = new Product();
     result = product.CheckPrice(PricingInformation, northwindConfig);
     return result;
 }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 15
0
        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;
        }
Esempio n. 16
0
 /// <summary>
 /// The Constructor.
 /// </summary>
 public NorthwindConnector()
 {
     _config = new NorthwindConfig("-");
 }
Esempio n. 17
0
        /// <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;
        }
Esempio n. 18
0
 /// <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;
 }
Esempio n. 19
0
        /// <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;
        }
Esempio n. 25
0
 /// <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);
            }
Esempio n. 27
0
        /// <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;
                }
            }
Esempio n. 29
0
        /// <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;
        }
Esempio n. 31
0
        /// <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;
            }
Esempio n. 33
0
        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;
            }
Esempio n. 36
0
        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;
        }
Esempio n. 37
0
        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;
        }