public virtual FeedEntry GetSyncTargetFeedEntry(SdataTransactionResult transactionResult) { FeedEntry result; if (!String.IsNullOrEmpty(transactionResult.LocalId)) { result = GetFeedEntry(transactionResult.LocalId); } else //result = PayloadFactory.CreateResourcePayload(this._resourceKind); #warning The Feed Entry should have a type... { result = new FeedEntry(); } if (!String.IsNullOrEmpty(transactionResult.Uuid)) { result.UUID = new Guid(transactionResult.Uuid); } if (transactionResult.HttpMethod == HttpMethod.DELETE) { result.IsDeleted = true; } return(result); }
public virtual SyncFeedEntry GetFeedEntry(SdataTransactionResult transactionResult) { SyncFeedEntry result; if (!String.IsNullOrEmpty(transactionResult.LocalId)) { result = GetFeedEntry(transactionResult.LocalId); } else { result = new SyncFeedEntry(); result.Uuid = transactionResult.Uuid; } if (result == null) { return(null); } //entry.Uuid = transactionResult.Uuid; result.HttpStatusCode = transactionResult.HttpStatus; result.HttpMessage = transactionResult.HttpMessage;; result.HttpMethod = transactionResult.HttpMethod; result.HttpLocation = transactionResult.Location; result.HttpETag = transactionResult.Etag; return(result); }
public void DoWork(IRequest request) { if (String.IsNullOrEmpty(_requestContext.ResourceKey)) { throw new RequestException("Please use single resource url"); } IEntityWrapper wrapper; wrapper = EntityWrapperFactory.Create(_requestContext.ResourceKind, _requestContext); SdataTransactionResult sdTrResult = wrapper.Delete(_requestContext.ResourceKey); if (sdTrResult == null) { throw new RequestException("Entity does not exists"); } if (sdTrResult.HttpStatus == System.Net.HttpStatusCode.OK) { request.Response.StatusCode = System.Net.HttpStatusCode.OK; } else { throw new RequestException(sdTrResult.HttpMessage); } }
public void Create(FeedEntry entry) { if (IsValid(entry)) { IFeedEntryEntityWrapper cWrapper = FeedEntryWrapperFactory.Create(_context.ResourceKind, _context); SdataTransactionResult trResult = cWrapper.Add(entry); if (trResult.HttpStatus == System.Net.HttpStatusCode.Created || trResult.HttpStatus == System.Net.HttpStatusCode.OK) { if (string.IsNullOrEmpty(entry.Id)) { entry.Id = trResult.Location; } _request.Response.FeedEntry = entry; _request.Response.Protocol.SendKnownResponseHeader(System.Net.HttpResponseHeader.Location, entry.Id); } else { _request.Response.StatusCode = trResult.HttpStatus; _request.Response.Diagnoses = new Diagnoses(); _request.Response.Diagnoses.Add(GetDiagnosis(trResult)); //throw new InvalidDataException(trResult.HttpStatus + ": " + trResult.HttpMessage); } } else { throw new RequestException("Please use valid single resource url"); } }
public void Update(FeedEntry entry, string id) { string resource = TrimApostophes(id); if (!string.IsNullOrEmpty(resource) && string.IsNullOrEmpty(entry.Key)) { entry.Key = resource; } if (IsValid(entry)) { SdataTransactionResult trResult = _wrapper.Update(entry); if (trResult.HttpStatus == System.Net.HttpStatusCode.OK) { Read(resource); } else { _request.Response.StatusCode = trResult.HttpStatus; _request.Response.Diagnoses = new Diagnoses(); _request.Response.Diagnoses.Add(GetDiagnosis(trResult)); } } else { throw new RequestException("Please use valid single resource url"); } }
public override SdataTransactionResult Update(PayloadBase payload, List <SyncFeedEntryLink> links) { //Transform account Document document = GetTransformedDocument(payload, links); AccountDocument accountDocument = (AccountDocument)_entity.GetDocumentTemplate(); accountDocument.Id = document.Id; accountDocument.CrmId = GetTradingAccountUuid(document.Id); accountDocument.addresses.documents.Add(document); // Update Document List <TransactionResult> transactionResults = new List <TransactionResult>(); _entity.Update(accountDocument, _context.Config, ref transactionResults); SdataTransactionResult sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, SupportedResourceKinds.tradingAccounts); if (sdTrResult != null) { sdTrResult.ResourceKind = _resourceKind; sdTrResult.HttpMessage = "PUT"; } return(sdTrResult); }
public void DoWork(IRequest request) { if (request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry) { throw new RequestException("Atom entry content type expected"); } if (!String.IsNullOrEmpty(_requestContext.ResourceKey)) { throw new RequestException("Please use resource url"); } // read entry from stream SyncFeedEntry entry = new SyncFeedEntry(); XmlReader reader = XmlReader.Create(request.Stream); reader.MoveToContent(); entry.ReadXml(reader, ResourceKindHelpers.GetPayloadType(_requestContext.ResourceKind)); IEntityWrapper wrapper = EntityWrapperFactory.Create(_requestContext.ResourceKind, _requestContext); Document document = wrapper.GetTransformedDocument(entry.Payload, entry.SyncLinks); if (!String.IsNullOrEmpty(document.Id)) { throw new RequestException("Entity alredy exists"); } // Add Document SdataTransactionResult sdTrResult = wrapper.Add(entry.Payload, entry.SyncLinks); if (sdTrResult == null) { throw new RequestException("Entity does not exists"); //????? } if ((sdTrResult.HttpStatus == System.Net.HttpStatusCode.OK) || (sdTrResult.HttpStatus == System.Net.HttpStatusCode.Created)) { // store correlation SyncFeedEntry responseEntry = wrapper.GetFeedEntry(sdTrResult.LocalId); SyncFeed feed = new SyncFeed(); feed.FeedType = FeedType.ResourceEntry; feed.Entries.Add(responseEntry); request.Response.StatusCode = System.Net.HttpStatusCode.Created; request.Response.Serializer = new SyncFeedSerializer(); request.Response.Feed = feed; request.Response.Protocol.SendUnknownResponseHeader("Location", responseEntry.Id); request.Response.ContentType = Sage.Common.Syndication.MediaType.AtomEntry; } else { throw new RequestException(sdTrResult.HttpMessage); } }
/// <summary> /// Sets the SdataTransactionResult.Diagnosis Object based on the Information in sdTrResult so the consumer gets a decent Error Message /// </summary> /// <param name="sdTrResult"></param> private static void AttachDiagnosis(SdataTransactionResult sdTrResult) { Diagnosis diag = new Diagnosis(); diag.Message = sdTrResult.HttpMessage; diag.Severity = Severity.Error; diag.ApplicationCode = sdTrResult.HttpStatus.ToString(); diag.SDataCode = DiagnosisCode.ApplicationDiagnosis; sdTrResult.Diagnosis = diag; }
private Diagnosis GetDiagnosis(SdataTransactionResult result) { Diagnosis d = result.Diagnosis; if (d == null) { d = new Diagnosis(); d.Message = result.HttpMessage; } return(d); }
private FeedEntry BuildFeedEntry(SdataTransactionResult transactionResult, IFeedEntryEntityWrapper wrapper) { // Create result feed entry FeedEntry feedEntry; if (null != transactionResult.Diagnosis) { /* set diagnosis */ feedEntry = new FeedEntry(); feedEntry.Diagnoses = new Diagnoses(); feedEntry.Diagnoses.Add(transactionResult.Diagnosis); } else { /* get and the resource payload */ // Get resource data feedEntry = wrapper.GetSyncTargetFeedEntry(transactionResult); // set id tag feedEntry.Id = feedEntry.Uri; // set title tag feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key); // set resource dependent links (self, edit, schema, template, post, service) feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry)); } // set updated feedEntry.Updated = DateTime.Now.ToLocalTime(); feedEntry.HttpStatusCode = transactionResult.HttpStatus; feedEntry.HttpMessage = transactionResult.HttpMessage;; if (transactionResult.HttpMethod == HttpMethod.PUT) { feedEntry.HttpMethod = "PUT"; } else if (transactionResult.HttpMethod == HttpMethod.POST) { feedEntry.HttpMethod = "POST"; } else { feedEntry.HttpMethod = "DELETE"; } feedEntry.HttpLocation = transactionResult.Location; return(feedEntry); }
internal SdataTransactionResult GetSdataTransactionResult( List <TransactionResult> transactions, string EndPoint, SupportedResourceKinds resource) { SdataTransactionResult result; // create default result result = new SdataTransactionResult(); result.ResourceKind = resource; result.HttpStatus = HttpStatusCode.BadRequest; if (transactions == null) { return(null); } if (transactions.Count == 0) { return(null); } PersistRelations(transactions); foreach (TransactionResult transaction in transactions) { SupportedResourceKinds res = GetSupportedResourceKind(transaction.EntityName); if (res == resource) { result.ResourceKind = resource; result.LocalId = transaction.ID; result.Uuid = transaction.CRMID; result.HttpMessage = transaction.Message; result.Location = EndPoint + "('" + transaction.ID + "')"; result.HttpStatus = Helper.GetHttpStatus(transaction.Status, transaction.Action); result.HttpMethod = Helper.GetHttpMethod(transaction.Action); } } foreach (TransactionResult transaction in transactions) { if (transaction.Status != TransactionStatus.Success) { result = new SdataTransactionResult(); result.ResourceKind = resource; result.HttpMessage = transaction.Message; result.HttpStatus = Helper.GetHttpStatus(transaction.Status, transaction.Action); return(result); } } return(result); }
public virtual SdataTransactionResult Delete(string id) { Identity identity = GetIdentity(id); List <TransactionResult> transactionResults = new List <TransactionResult>(); Document document = _entity.GetDocumentTemplate(); document.Id = id; document.LogState = LogState.Deleted; _entity.Delete(document, _context.Config, ref transactionResults); SdataTransactionResult sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, _resourceKind); return(sdTrResult); }
public virtual SdataTransactionResult Add(FeedEntry payload) { Document document = GetTransformedDocument(payload); List <TransactionResult> transactionResults = new List <TransactionResult>(); _entity.Add(document, _context.Config, ref transactionResults); SdataTransactionResult sdTrResult = GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, _resourceKind); if (sdTrResult != null) { sdTrResult.HttpMethod = HttpMethod.POST; } return(sdTrResult); }
public virtual SdataTransactionResult Add(PayloadBase payload, List <SyncFeedEntryLink> links) { Document document = GetTransformedDocument(payload, links); List <TransactionResult> transactionResults = new List <TransactionResult>(); _entity.Add(document, _context.Config, ref transactionResults); SdataTransactionResult sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, _resourceKind); if (sdTrResult != null) { sdTrResult.HttpMessage = "POST"; } return(sdTrResult); }
public override SdataTransactionResult Update(PayloadBase payload, List <SyncFeedEntryLink> links) { //Transform account Document document = GetTransformedDocument(payload, links); string id; string accountId; id = document.Id; if (id.EndsWith(Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix)) { accountId = id.Replace(Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix, ""); } else if (id.EndsWith(Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix)) { accountId = id.Replace(Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix, ""); } else { return(null); } AccountDocument accountDocument = (AccountDocument)_entity.GetDocumentTemplate(); accountDocument.Id = accountId; accountDocument.CrmId = GetTradingAccountUuid(document.Id); accountDocument.phones.documents.Add(document); // Update Document List <TransactionResult> transactionResults = new List <TransactionResult>(); _entity.Update(accountDocument, _context.Config, ref transactionResults); SdataTransactionResult sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, SupportedResourceKinds.phoneNumbers); if (sdTrResult != null) { sdTrResult.ResourceKind = _resourceKind; sdTrResult.HttpMessage = "PUT"; } return(sdTrResult); }
public void Delete(string id) { if (id == null) { // The resource key must exists in url throw new RequestException("Please use single resource url"); } SdataTransactionResult sdTrResult = _wrapper.Delete(_context.ResourceKey); if (sdTrResult == null) { throw new RequestException("Entity does not exists"); } if (sdTrResult.HttpStatus == System.Net.HttpStatusCode.OK) { _request.Response.StatusCode = System.Net.HttpStatusCode.OK; } else { throw new RequestException(sdTrResult.HttpMessage); } }
public override SdataTransactionResult Add(PayloadBase payload, List <SyncFeedEntryLink> links) { string accountUuid = ""; SdataTransactionResult sdTrResult; PostalAddressPayload addressPayload = payload as PostalAddressPayload; if ((addressPayload.PostalAddresstype.primacyIndicatorSpecified) && addressPayload.PostalAddresstype.primacyIndicator) { // is primary } else if (addressPayload.PostalAddresstype.type == postalAddressTypeenum.Correspondance) { // is also primary adress } else { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Only primary addresses suported"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = SupportedResourceKinds.postalAddresses; sdTrResult.Uuid = StringToGuid(addressPayload.PostalAddresstype.uuid); return(sdTrResult); } foreach (SyncFeedEntryLink link in links) { if ((!String.IsNullOrEmpty(link.PayloadPath)) && link.PayloadPath.Equals(_tradingAccountUuidPayloadPath, StringComparison.InvariantCultureIgnoreCase)) { accountUuid = link.Uuid; break; } } if (String.IsNullOrEmpty(accountUuid)) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account UUID was missing"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = StringToGuid(addressPayload.PostalAddresstype.uuid); return(sdTrResult); } string accountId = GetTradingAccountLocalId(accountUuid); if (String.IsNullOrEmpty(accountId)) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = String.Format("Trading Account UUID {0} was not linked", accountUuid); sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = StringToGuid(addressPayload.PostalAddresstype.uuid); return(sdTrResult); } Account account = new Account(); Identity accIdentity = new Identity(account.EntityName, accountId); AccountDocument accountDocument = account.GetDocument( accIdentity, _emptyToken, _context.Config) as AccountDocument; Document document = null; bool doAdd = false; if (accountDocument.addresses.documents.Count == 0) { document = GetTransformedDocument(payload, links); accountDocument.CrmId = GetTradingAccountUuid(document.Id); accountDocument.addresses.documents.Add(document); doAdd = true; } else { AddressDocument addressdocument = accountDocument.addresses.documents[0] as AddressDocument; if (addressdocument.address1.IsNull && addressdocument.address2.IsNull && addressdocument.address3.IsNull && addressdocument.address4.IsNull && addressdocument.City.IsNull) { document = GetTransformedDocument(payload, links); accountDocument.CrmId = GetTradingAccountUuid(document.Id); accountDocument.addresses.documents[0] = document; doAdd = true; } } if (!doAdd) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account has already a primary address"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = StringToGuid(addressPayload.PostalAddresstype.uuid); return(sdTrResult); } List <TransactionResult> transactionResults = new List <TransactionResult>(); account.Update(accountDocument, _context.Config, ref transactionResults); sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, SupportedResourceKinds.tradingAccounts); if (sdTrResult != null) { sdTrResult.ResourceKind = _resourceKind; sdTrResult.HttpMessage = "POST"; } return(sdTrResult); }
public override SdataTransactionResult Update(Sage.Common.Syndication.FeedEntry payload) { SdataTransactionResult tmpTransactionResult; if (!(payload is SalesOrderLineFeedEntry)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder payload missing"); return(tmpTransactionResult); } SalesOrderLineFeedEntry soLine = payload as SalesOrderLineFeedEntry; Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter detailsTableAdapter = new Order_DetailsTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order order = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order(); int productId; int orderId; if (GetLocalIds(payload.Key, out orderId, out productId)) { using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { try { detailsTableAdapter.Connection = connection; int recordCount = detailsTableAdapter.FillBy(order.Order_Details, orderId); if (recordCount == 0) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = payload.Key; tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder not found"); return(tmpTransactionResult); } foreach (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow detailsRow in order.Order_Details.Rows) { if (detailsRow.ProductID == productId) { detailsRow.ModifyUser = _context.Config.CrmUser; detailsRow.ModifyID = _context.Config.SequenceNumber; if (soLine.IsPropertyChanged("quantity")) { detailsRow.Quantity = Convert.ToInt16(soLine.quantity); } else { detailsRow.Quantity = 0; } if (soLine.IsPropertyChanged("initialPrice")) { detailsRow.UnitPrice = (Decimal)soLine.initialPrice; } else { detailsRow.UnitPrice = 0; } if ((!soLine.IsPropertyChanged("discountTotal")) || (detailsRow.Quantity == 0) || (detailsRow.UnitPrice == 0)) { detailsRow.Discount = (float)0; } else { // discountPC = discountsum / qunatity * listprice //detailRow.Discount = Convert.ToSingle((decimal)lineItemDoc.discountsum.Value / ((decimal)detailRow.Quantity * detailRow.UnitPrice)); float discount = Convert.ToSingle((decimal)soLine.discountTotal / (detailsRow.UnitPrice)); if (discount > 1) { discount = 0; } detailsRow.Discount = discount; } break; } } detailsTableAdapter.Update(order.Order_Details); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = payload.Key; tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.OK; return(tmpTransactionResult); } catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = payload.Key; tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } } } tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = payload.Key; tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = "Not found"; return(tmpTransactionResult); }
public override SdataTransactionResult Delete(string id) { SdataTransactionResult tmpTransactionResult; Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter detailsTableAdapter = new Order_DetailsTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order order = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order(); int productId; int orderId; if (GetLocalIds(id, out orderId, out productId)) { using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { try { detailsTableAdapter.Connection = connection; int recordCount = detailsTableAdapter.FillBy(order.Order_Details, orderId); if (recordCount == 0) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = id; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder not found"); return(tmpTransactionResult); } foreach (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow row in order.Order_Details.Rows) { if (row.ProductID == productId) { row.Delete(); break; } } detailsTableAdapter.Update(order.Order_Details); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = id; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.OK; return(tmpTransactionResult); } catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = id; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } } } tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = id; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = "Not found"; return(tmpTransactionResult); }
// 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; } }
public override SdataTransactionResult Add(FeedEntry entry) { string accountUuid = string.Empty; SdataTransactionResult sdTrResult; ContactFeedEntry contactEntry = entry as ContactFeedEntry; if (contactEntry.primacyIndicator) { // is primary } else { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Only primary contacts supported"; sdTrResult.HttpMethod = HttpMethod.POST; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = SupportedResourceKinds.contacts; sdTrResult.Uuid = contactEntry.UUID.ToString(); AttachDiagnosis(sdTrResult); return(sdTrResult); } if (contactEntry.tradingAccount != null) { accountUuid = contactEntry.tradingAccount.UUID.ToString(); } if (String.IsNullOrEmpty(accountUuid) || Guid.Empty.ToString() == accountUuid) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account UUID was missing"; sdTrResult.HttpMethod = HttpMethod.POST; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = contactEntry.UUID.ToString(); AttachDiagnosis(sdTrResult); return(sdTrResult); } string accountId = GetTradingAccountLocalId(accountUuid); if (String.IsNullOrEmpty(accountId)) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = String.Format("Trading Account UUID {0} was not linked", accountUuid); sdTrResult.HttpMethod = HttpMethod.POST; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = contactEntry.UUID.ToString(); AttachDiagnosis(sdTrResult); return(sdTrResult); } Account account = new Account(); Identity accIdentity = new Identity(account.EntityName, accountId); AccountDocument accountDocument = account.GetDocument( accIdentity, _emptyToken, _context.Config) as AccountDocument; accountDocument.CrmId = accountUuid; Document document = null; bool doAdd = false; document = GetTransformedDocument(entry); if (accountDocument.people.documents.Count == 0) { accountDocument.people.documents.Add(document); doAdd = true; } else { PersonDocument personDocument = accountDocument.people.documents[0] as PersonDocument; if (personDocument.firstname.IsNull && personDocument.lastname.IsNull) { accountDocument.people.documents[0] = document; doAdd = true; } } if (!doAdd) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account has already a primary contact"; sdTrResult.HttpMethod = HttpMethod.POST; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = contactEntry.UUID.ToString(); AttachDiagnosis(sdTrResult); return(sdTrResult); } List <TransactionResult> transactionResults = new List <TransactionResult>(); account.Update(accountDocument, _context.Config, ref transactionResults); sdTrResult = GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, SupportedResourceKinds.tradingAccounts); if (sdTrResult != null) { sdTrResult.ResourceKind = _resourceKind; sdTrResult.HttpMessage = "POST"; } return(sdTrResult); }
private FeedEntry BuildFeedEntry(SdataTransactionResult transactionResult, IFeedEntryEntityWrapper wrapper) { // Create result feed entry FeedEntry feedEntry; if (null != transactionResult.Diagnosis) { /* set diagnosis */ feedEntry = new FeedEntry(); feedEntry.Diagnoses = new Diagnoses(); feedEntry.Diagnoses.Add(transactionResult.Diagnosis); } else { /* get and the resource payload */ // Get resource data feedEntry = wrapper.GetSyncTargetFeedEntry(transactionResult); // set id tag feedEntry.Id = feedEntry.Uri; // set title tag feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key); // set resource dependent links (self, edit, schema, template, post, service) feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry)); } // set updated feedEntry.Updated = DateTime.Now.ToLocalTime(); feedEntry.HttpStatusCode = transactionResult.HttpStatus; feedEntry.HttpMessage = transactionResult.HttpMessage; ; if (transactionResult.HttpMethod == HttpMethod.PUT) feedEntry.HttpMethod = "PUT"; else if (transactionResult.HttpMethod == HttpMethod.POST) feedEntry.HttpMethod = "POST"; else feedEntry.HttpMethod = "DELETE"; feedEntry.HttpLocation = transactionResult.Location; return feedEntry; }
public override SdataTransactionResult Delete(string localID) { SdataTransactionResult tmpTransactionResult; Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.OrdersTableAdapter tableAdapter = new OrdersTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter detailsTableAdapter = new Order_DetailsTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order order = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order(); int id; if (!(Int32.TryParse(localID, out id))) { id = 0; } int recordCount; using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { try { tableAdapter.Connection = connection; recordCount = tableAdapter.FillBy(order.Orders, id); if (recordCount == 0) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = localID; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder not found"); return(tmpTransactionResult); } detailsTableAdapter.Connection = connection; detailsTableAdapter.FillBy(order.Order_Details, id); foreach (DataRow row in order.Order_Details.Rows) { row.Delete(); } order.Orders[0].Delete(); detailsTableAdapter.Update(order.Order_Details); tableAdapter.Update(order.Orders); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = localID; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.OK; return(tmpTransactionResult); } catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.LocalId = localID; tmpTransactionResult.HttpMethod = HttpMethod.DELETE; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } } }
public override SdataTransactionResult Update(Sage.Common.Syndication.FeedEntry payload) { SdataTransactionResult tmpTransactionResult; SalesOrderFeedEntry salesorder = null; #region check input values if (!(payload is SalesOrderFeedEntry)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder payload missing"); return(tmpTransactionResult); } salesorder = (payload as SalesOrderFeedEntry); if (salesorder == null) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder payload missing"); return(tmpTransactionResult); } string customerID = ""; if (salesorder.tradingAccount != null) { customerID = GetLocalId(salesorder.tradingAccount.UUID, SupportedResourceKinds.tradingAccounts); } if (String.IsNullOrEmpty(customerID)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("Trading Acount Id missing"); return(tmpTransactionResult); } if (!customerID.StartsWith(Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("Salesorder submission is only supported by customers"); return(tmpTransactionResult); } #endregion Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.OrdersTableAdapter tableAdapter = new OrdersTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter detailsTableAdapter = new Order_DetailsTableAdapter(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order order = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order(); int id; if (!(Int32.TryParse(payload.Key, out id))) { id = 0; } int recordCount; using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { tableAdapter.Connection = connection; recordCount = tableAdapter.FillBy(order.Orders, id); if (recordCount == 0) { return(null); } detailsTableAdapter.Connection = connection; detailsTableAdapter.FillBy(order.Order_Details, id); } Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.OrdersRow row = (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.OrdersRow)order.Orders[0]; #region fill dataset from document try { if (!salesorder.IsPropertyChanged("date")) { row.SetOrderDateNull(); } else { row.OrderDate = salesorder.date; } if (!salesorder.IsPropertyChanged("dueDate")) { row.SetRequiredDateNull(); } else { row.RequiredDate = (DateTime)salesorder.dueDate; } //if (orderDoc.shippedvia.IsNull) // newOrder.SetShipViaNull(); //else // newOrder.ShipVia = (int)orderDoc.shippedvia.Value; if (salesorder.postalAddresses == null || salesorder.postalAddresses.Entries.Count == 0) { row.SetShipAddressNull(); row.SetShipCityNull(); row.SetShipCountryNull(); row.SetShipPostalCodeNull(); } else { PostalAddressFeedEntry postadress = salesorder.postalAddresses.Entries[0]; row.ShipAddress = postadress.address1; row.ShipCity = postadress.townCity; row.ShipPostalCode = postadress.zipPostCode; row.ShipCountry = postadress.country; } if (!salesorder.IsPropertyChanged("carrierTotalPrice")) { row.Freight = (decimal)0; } else { row.Freight = (decimal)salesorder.carrierTotalPrice; } //row.CreateUser = _context.Config.CrmUser; row.ModifyUser = _context.Config.CrmUser; //row.CreateID = _context.Config.SequenceNumber; row.ModifyID = _context.Config.SequenceNumber; Guid itemUuid; List <Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow> rowsToDelete = new List <Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow>(); List <Guid> itemUuids = new List <Guid>(); if (salesorder.salesOrderLines != null) { foreach (SalesOrderLineFeedEntry soLine in salesorder.salesOrderLines.Entries) { if ((soLine.UUID != null && soLine.UUID != Guid.Empty) && (!itemUuids.Contains(soLine.UUID))) { itemUuids.Add(soLine.UUID); } } } foreach (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow detailsRow in order.Order_Details) { string itemId = detailsRow.OrderID.ToString() + "-" + detailsRow.ProductID.ToString(); itemUuid = GetUuid(itemId, "", SupportedResourceKinds.salesOrderLines); if (itemUuids.Contains(itemUuid)) { foreach (SalesOrderLineFeedEntry soLine in salesorder.salesOrderLines.Entries) { if (soLine.UUID.Equals(itemUuid)) { if (soLine.IsDeleted) { rowsToDelete.Add(detailsRow); break; } /*if (soLine.IsEmpty) * { * break; * }*/ detailsRow.ModifyUser = _context.Config.CrmUser; detailsRow.ModifyID = _context.Config.SequenceNumber; if (soLine.IsPropertyChanged("quantity")) { detailsRow.Quantity = Convert.ToInt16(soLine.quantity); } else { detailsRow.Quantity = 0; } if (soLine.IsPropertyChanged("initialPrice")) { detailsRow.UnitPrice = (Decimal)soLine.initialPrice; } else { detailsRow.UnitPrice = 0; } if ((!soLine.IsPropertyChanged("discountTotal")) || (detailsRow.Quantity == 0) || (detailsRow.UnitPrice == 0)) { detailsRow.Discount = (float)0; } else { // discountPC = discountsum / qunatity * listprice //detailRow.Discount = Convert.ToSingle((decimal)lineItemDoc.discountsum.Value / ((decimal)detailRow.Quantity * detailRow.UnitPrice)); float discount = Convert.ToSingle((decimal)soLine.discountTotal / (detailsRow.UnitPrice)); if (discount > 1) { discount = 0; } detailsRow.Discount = discount; } break; } } itemUuids.Remove(itemUuid); } else { //delete item rowsToDelete.Add(detailsRow); } } if (salesorder.salesOrderLines != null) { foreach (SalesOrderLineFeedEntry soLine in salesorder.salesOrderLines.Entries) { Guid soUuid = soLine.UUID; if (itemUuids.Contains(soUuid)) { itemUuids.Remove(soUuid); } else { continue; } try { Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow detailRow = order.Order_Details.NewOrder_DetailsRow(); Guid productUuid = soLine.commodity.UUID; string productIdString = GetLocalId(productUuid, SupportedResourceKinds.commodities); int productID; if (!int.TryParse(productIdString, out productID)) { continue; } string sorderID = payload.Key + "-" + productID.ToString(); detailRow.OrderID = Convert.ToInt32(payload.Key); detailRow.ProductID = productID; if (soLine.IsPropertyChanged("quantity")) { detailRow.Quantity = Convert.ToInt16(soLine.quantity); } else { detailRow.Quantity = 0; } if (soLine.IsPropertyChanged("initialPrice")) { detailRow.UnitPrice = (Decimal)soLine.initialPrice; } else { detailRow.UnitPrice = 0; } if ((!soLine.IsPropertyChanged("discountTotal")) || (detailRow.Quantity == 0) || (detailRow.UnitPrice == 0)) { detailRow.Discount = (float)0; } else { // discountPC = discountsum / qunatity * listprice //detailRow.Discount = Convert.ToSingle((decimal)lineItemDoc.discountsum.Value / ((decimal)detailRow.Quantity * detailRow.UnitPrice)); float discount = Convert.ToSingle((decimal)soLine.discountTotal / (detailRow.UnitPrice)); if (discount > 1) { discount = 0; } detailRow.Discount = discount; } detailRow.CreateUser = _context.Config.CrmUser; detailRow.ModifyUser = _context.Config.CrmUser; detailRow.CreateID = _context.Config.SequenceNumber; detailRow.ModifyID = _context.Config.SequenceNumber; order.Order_Details.AddOrder_DetailsRow(detailRow); } // this error occours in case of invalid data types catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } } } using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { OleDbTransaction transaction = null; try { connection.Open(); transaction = connection.BeginTransaction(); tableAdapter.Connection = connection; detailsTableAdapter.Connection = connection; tableAdapter.SetTransaction(transaction); detailsTableAdapter.SetTransaction(transaction); foreach (Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow detailsRow in rowsToDelete) { detailsTableAdapter.Delete(detailsRow.OrderID, detailsRow.ProductID, detailsRow.UnitPrice, detailsRow.Quantity, detailsRow.Discount, detailsRow.CreateID, detailsRow.CreateUser, detailsRow.ModifyID, detailsRow.ModifyUser); } tableAdapter.Update(order.Orders); detailsTableAdapter.Update(order.Order_Details); transaction.Commit(); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.OK; tmpTransactionResult.LocalId = payload.Key; return(tmpTransactionResult); } catch (Exception transactionException) { if (transaction != null) { transaction.Rollback(); } throw; } } } catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.ToString(); return(tmpTransactionResult); } #endregion }
public override SdataTransactionResult Add(Sage.Common.Syndication.FeedEntry payload) { SdataTransactionResult tmpTransactionResult; SalesOrderFeedEntry salesorder = null; if (!(payload is SalesOrderFeedEntry)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder payload missing"); return(tmpTransactionResult); } salesorder = (payload as SalesOrderFeedEntry); if (salesorder == null) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("salesorder payload missing"); return(tmpTransactionResult); } #region check input values if (payload == null) { return(null); } string customerID = ""; if (salesorder.tradingAccount != null) { customerID = GetLocalId(salesorder.tradingAccount.UUID, SupportedResourceKinds.tradingAccounts); } if (String.IsNullOrEmpty(customerID)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("Trading Acount Id missing"); return(tmpTransactionResult); } if (!customerID.StartsWith(Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix)) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.PUT; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("Salesorder submission is only supported by customers"); return(tmpTransactionResult); } #endregion Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.OrdersTableAdapter tableAdapter; Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter detailsTableAdapter; Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order order = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order(); Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.OrdersRow newOrder = order.Orders.NewOrdersRow(); customerID = customerID.Substring(Sage.Integration.Northwind.Application.API.Constants.CustomerIdPrefix.Length); newOrder.CustomerID = customerID; #region get Company Name DataSet dataSet = new DataSet(); OleDbDataAdapter dataAdapter; string sqlQuery = "Select CompanyName from Customers where CustomerID = '" + customerID + "'"; try { using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { dataAdapter = new OleDbDataAdapter(sqlQuery, connection); if (dataAdapter.Fill(dataSet, "Customers") == 0) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = ("trading account not found"); return(tmpTransactionResult); } newOrder.ShipName = dataSet.Tables[0].Rows[0][0].ToString(); } } catch (Exception e) { throw; } #endregion #region fill dataset from document try { if (!salesorder.IsPropertyChanged("date") || salesorder.date == null) { newOrder.SetOrderDateNull(); } else { newOrder.OrderDate = salesorder.date; } if (!salesorder.IsPropertyChanged("dueDate") || salesorder.dueDate == null) { newOrder.SetRequiredDateNull(); } else { newOrder.RequiredDate = (DateTime)salesorder.dueDate; } //if (orderDoc.shippedvia.IsNull) // newOrder.SetShipViaNull(); //else // newOrder.ShipVia = (int)orderDoc.shippedvia.Value; if (salesorder.postalAddresses == null || salesorder.postalAddresses.Entries.Count == 0) { newOrder.SetShipAddressNull(); newOrder.SetShipCityNull(); newOrder.SetShipCountryNull(); newOrder.SetShipPostalCodeNull(); } else { PostalAddressFeedEntry postadress = salesorder.postalAddresses.Entries[0]; newOrder.ShipAddress = postadress.address1; newOrder.ShipCity = postadress.townCity; newOrder.ShipPostalCode = postadress.zipPostCode; newOrder.ShipCountry = postadress.country; } if (!salesorder.IsPropertyChanged("carrierTotalPrice")) { newOrder.Freight = (decimal)0; } else { newOrder.Freight = (decimal)salesorder.carrierTotalPrice; } newOrder.CreateUser = _context.Config.CrmUser; newOrder.ModifyUser = _context.Config.CrmUser; newOrder.CreateID = _context.Config.SequenceNumber; newOrder.ModifyID = _context.Config.SequenceNumber; } catch (Exception e) { tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.ToString(); return(tmpTransactionResult); } #endregion using (OleDbConnection connection = new OleDbConnection(_context.Config.ConnectionString)) { OleDbTransaction transaction = null; try { connection.Open(); transaction = connection.BeginTransaction(); tableAdapter = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.OrdersTableAdapter(); tableAdapter.Connection = connection; detailsTableAdapter = new Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.OrderTableAdapters.Order_DetailsTableAdapter(); detailsTableAdapter.Connection = connection; tableAdapter.SetTransaction(transaction); detailsTableAdapter.SetTransaction(transaction); order.Orders.AddOrdersRow(newOrder); tableAdapter.Update(order.Orders); OleDbCommand Cmd = new OleDbCommand("SELECT @@IDENTITY", connection); Cmd.Transaction = transaction; object lastid = Cmd.ExecuteScalar(); payload.Key = ((int)lastid).ToString(); // add line Items Sage.Integration.Northwind.Adapter.Data.SalesOrders.DataSets.Order.Order_DetailsRow detailRow; Hashtable addedProductsProducts; addedProductsProducts = new Hashtable(); int productID; int productIndex = 0; if (salesorder.salesOrderLines != null) { foreach (SalesOrderLineFeedEntry salesOrderLine in salesorder.salesOrderLines.Entries) { try { string productIdString = ""; productID = 0; if (salesOrderLine.commodity != null && salesOrderLine.commodity.UUID != null && salesOrderLine.commodity.UUID != Guid.Empty) { productIdString = GetLocalId(salesOrderLine.commodity.UUID, SupportedResourceKinds.commodities); if (!int.TryParse(productIdString, out productID)) { productID = 0; } } if (addedProductsProducts.Contains(productID)) { transaction.Rollback(); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = "Order contains a product twice"; return(tmpTransactionResult); } addedProductsProducts.Add(productID, productID); detailRow = order.Order_Details.NewOrder_DetailsRow(); salesOrderLine.Key = payload.Key + "-" + productID.ToString(); detailRow.OrderID = Convert.ToInt32(payload.Key); detailRow.ProductID = productID; if (salesOrderLine.IsPropertyChanged("quantity")) { detailRow.Quantity = Convert.ToInt16(salesOrderLine.quantity); } else { detailRow.Quantity = 0; } if (salesOrderLine.IsPropertyChanged("initialPrice")) { detailRow.UnitPrice = (Decimal)salesOrderLine.initialPrice; } else { detailRow.UnitPrice = 0; } if ((!salesOrderLine.IsPropertyChanged("discountTotal")) || (detailRow.Quantity == 0) || (detailRow.UnitPrice == 0)) { detailRow.Discount = (float)0; } else { // discountPC = discountsum / qunatity * listprice //detailRow.Discount = Convert.ToSingle((decimal)lineItemDoc.discountsum.Value / ((decimal)detailRow.Quantity * detailRow.UnitPrice)); float discount = Convert.ToSingle((decimal)salesOrderLine.discountTotal / (detailRow.UnitPrice)); if (discount > 1) { discount = 0; } detailRow.Discount = discount; } detailRow.CreateUser = _context.Config.CrmUser; detailRow.ModifyUser = _context.Config.CrmUser; detailRow.CreateID = _context.Config.SequenceNumber; detailRow.ModifyID = _context.Config.SequenceNumber; } // this error occours in case of invalid data types catch (Exception e) { transaction.Rollback(); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } order.Order_Details.AddOrder_DetailsRow(detailRow); productIndex++; } } // here could an error ouucour in case on broken database connection // or of same invalid constraints which are unhandled before try { detailsTableAdapter.Update(order.Order_Details); } catch (Exception e) { transaction.Rollback(); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.BadRequest; tmpTransactionResult.HttpMessage = e.Message; return(tmpTransactionResult); } transaction.Commit(); tmpTransactionResult = new SdataTransactionResult(); tmpTransactionResult.HttpMethod = HttpMethod.POST; tmpTransactionResult.ResourceKind = _resourceKind; tmpTransactionResult.HttpStatus = System.Net.HttpStatusCode.Created; tmpTransactionResult.LocalId = payload.Key; return(tmpTransactionResult); } catch (Exception transactionException) { if (transaction != null) { transaction.Rollback(); } throw; } } }
/// <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); }
public void DoWork(IRequest request) { if (request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry) { throw new RequestException("Atom entry content type expected"); } if (String.IsNullOrEmpty(_requestContext.ResourceKey)) { throw new RequestException("Please use single resource url"); } //SupportedResourceKinds resKind = _requestContext.ResourceKind; //switch (resKind) //{ // case SupportedResourceKinds.tradingAccounts: // case SupportedResourceKinds.contacts: // case SupportedResourceKinds.phoneNumbers: // case SupportedResourceKinds.postalAddresses: // break; // default: // throw new RequestException("Put is not Supported for requested resource"); //} // read entry from stream SyncFeedEntry entry = new SyncFeedEntry(); XmlReader reader = XmlReader.Create(request.Stream); reader.MoveToContent(); entry.ReadXml(reader, ResourceKindHelpers.GetPayloadType(_requestContext.ResourceKind)); IEntityWrapper wrapper = EntityWrapperFactory.Create(_requestContext.ResourceKind, _requestContext); Token emptyToken = new Token(); Identity identity = wrapper.GetIdentity(_requestContext.ResourceKey); Document originalDocument = wrapper.Entity.GetDocument(identity, emptyToken, _requestContext.Config); if (originalDocument.LogState == LogState.Deleted) { throw new RequestException("Entity does not exists"); } entry.Payload.LocalID = _requestContext.ResourceKey; SdataTransactionResult sdTrResult = wrapper.Update(entry.Payload, entry.SyncLinks); if (sdTrResult == null) { SyncFeedEntry responseEntry = wrapper.GetFeedEntry(_requestContext.ResourceKey); SyncFeed feed = new SyncFeed(); feed.FeedType = FeedType.ResourceEntry; feed.Entries.Add(responseEntry); request.Response.Serializer = new SyncFeedSerializer(); request.Response.Feed = feed; request.Response.ContentType = Sage.Common.Syndication.MediaType.AtomEntry; } else if (sdTrResult.HttpStatus == System.Net.HttpStatusCode.OK) { SyncFeedEntry responseEntry = wrapper.GetFeedEntry(_requestContext.ResourceKey); SyncFeed feed = new SyncFeed(); feed.FeedType = FeedType.ResourceEntry; feed.Entries.Add(responseEntry); request.Response.Serializer = new SyncFeedSerializer(); request.Response.Feed = feed; request.Response.ContentType = Sage.Common.Syndication.MediaType.AtomEntry; } else { throw new RequestException(sdTrResult.HttpMessage); } }
// 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; } }
public override SdataTransactionResult Add(PayloadBase payload, List <SyncFeedEntryLink> links) { string accountUuid = ""; SdataTransactionResult sdTrResult; PhoneNumberPayload phoneNumberPayload = payload as PhoneNumberPayload; bool isFax = false;; bool isPhone = false; if (phoneNumberPayload.PhoneNumbertype.type.Equals("general", StringComparison.InvariantCultureIgnoreCase)) { isPhone = true; } else if (phoneNumberPayload.PhoneNumbertype.type.Equals("fax", StringComparison.InvariantCultureIgnoreCase)) { isFax = true; } else { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Only primary phonenumbers with type general and fax where accepted"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = phoneNumberPayload.SyncUuid; return(sdTrResult); } foreach (SyncFeedEntryLink link in links) { if ((!String.IsNullOrEmpty(link.PayloadPath)) && link.PayloadPath.Equals(_tradingAccountUuidPayloadPath, StringComparison.InvariantCultureIgnoreCase)) { accountUuid = link.Uuid; break; } } if (String.IsNullOrEmpty(accountUuid)) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account UUID was missing"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = phoneNumberPayload.SyncUuid; return(sdTrResult); } string accountId = GetTradingAccountLocalId(accountUuid); if (String.IsNullOrEmpty(accountId)) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = String.Format("Trading Account UUID {0} was not linked", accountUuid); sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = phoneNumberPayload.SyncUuid; return(sdTrResult); } Account account = new Account(); Identity accIdentity = new Identity(account.EntityName, accountId); AccountDocument accountDocument = account.GetDocument( accIdentity, _emptyToken, _context.Config) as AccountDocument; Document document = null; bool doAdd = false; document = GetTransformedDocument(payload, links); if (isPhone) { document.Id = accountId + Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix; } if (isFax) { document.Id = accountId + Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix; } if (accountDocument.addresses.documents.Count == 0) { accountDocument.CrmId = GetTradingAccountUuid(document.Id); accountDocument.phones.documents.Add(document); doAdd = true; } else { for (int index = 0; index < accountDocument.phones.documents.Count; index++) { if (accountDocument.phones.documents[index].Id.Equals(document.Id, StringComparison.InvariantCultureIgnoreCase)) { if (((PhoneDocument)accountDocument.phones.documents[index]).number.IsNull) { doAdd = true; accountDocument.phones.documents[index] = document; } break; } } } if (!doAdd) { sdTrResult = new SdataTransactionResult(); sdTrResult.HttpMessage = "Trading Account has already this primary phone type"; sdTrResult.HttpMethod = "POST"; sdTrResult.HttpStatus = System.Net.HttpStatusCode.Forbidden; sdTrResult.ResourceKind = _resourceKind; sdTrResult.Uuid = phoneNumberPayload.SyncUuid; return(sdTrResult); } List <TransactionResult> transactionResults = new List <TransactionResult>(); account.Update(accountDocument, _context.Config, ref transactionResults); sdTrResult = Helper.GetSdataTransactionResult(transactionResults, _context.OriginEndPoint, SupportedResourceKinds.tradingAccounts); if (sdTrResult != null) { sdTrResult.ResourceKind = _resourceKind; sdTrResult.HttpMessage = "POST"; } return(sdTrResult); }