/// <summary> /// This method first connects to the Organization service. Afterwards, a /// quote is created. This quote is then converted to an order, and the pricing /// is unlocked and relocked. This is followed by the order being converted /// to an invoice, and the pricing is locked then unlocked. /// </summary> /// <param name="serverConfig">Contains server connection information.</param> /// <param name="promptforDelete">When True, the user will be prompted to delete all /// created entities.</param> public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { try { //<snippetProcessingQuotesAndSalesOrders1> // Connect to the Organization service. // The using statement assures that the service proxy will be properly disposed. using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials)) { // This statement is required to enable early-bound type support. _serviceProxy.EnableProxyTypes(); CreateRequiredRecords(); #region Create Opportunities // Create an opportunity var crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _opportunityId = _serviceProxy.Create(crmOpportunity); crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Another Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _loseOpportunityId = _serviceProxy.Create(crmOpportunity); Console.WriteLine("Opportunities created."); #endregion #region Win Opportunity //<snippetWinOpportunity> // Close the opportunity as won var winOppRequest = new WinOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _opportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Won) }; _serviceProxy.Execute(winOppRequest); Console.WriteLine("Opportunity closed as Won."); //</snippetWinOpportunity> #endregion #region Lose Opportunity //<snippetLoseOpportunity> var loseOppRequest = new LoseOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _loseOpportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Canceled) }; _serviceProxy.Execute(loseOppRequest); Console.WriteLine("Opportunity closed as Lost."); //</snippetLoseOpportunity> #endregion #region Convert Opportunity to a Quote //<snippetGenerateQuoteFromOpportunity> // Convert the opportunity to a quote var genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; var genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote quote = genQuoteFromOppResponse.Entity.ToEntity<Quote>(); _quoteId = quote.Id; Console.WriteLine("Quote generated from the Opportunity."); //</snippetGenerateQuoteFromOpportunity> #endregion #region Close Quote //<snippetCloseQuote> // convert the opportunity to a quote genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote closeQuote = genQuoteFromOppResponse.Entity.ToEntity<Quote>(); _closeQuoteId = closeQuote.Id; // Activate the quote SetStateRequest activateQuote = new SetStateRequest() { EntityMoniker = closeQuote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); // Close the quote CloseQuoteRequest closeQuoteRequest = new CloseQuoteRequest() { QuoteClose = new QuoteClose() { QuoteId = closeQuote.ToEntityReference(), Subject = "Quote Close " + DateTime.Now.ToString() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(closeQuoteRequest); Console.WriteLine("Quote Closed"); //</snippetCloseQuote> #endregion #region Create Quote's Product // Set the quote's product QuoteDetail quoteDetail = new QuoteDetail() { ProductId = new EntityReference(Product.EntityLogicalName, _productId), Quantity = 1, QuoteId = quote.ToEntityReference(), UoMId = new EntityReference(UoM.EntityLogicalName, _defaultUnitId) }; _quoteDetailId = _serviceProxy.Create(quoteDetail); Console.WriteLine("Quote Product created."); // Activate the quote activateQuote = new SetStateRequest() { EntityMoniker = quote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); Console.WriteLine("Quote activated."); //<snippetWinQuote> // Mark the quote as won // Note: this is necessary in order to convert a quote into a // SalesOrder. WinQuoteRequest winQuoteRequest = new WinQuoteRequest() { QuoteClose = new QuoteClose() { Subject = "Quote Close" + DateTime.Now.ToString(), QuoteId = quote.ToEntityReference() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(winQuoteRequest); Console.WriteLine("Quote won."); //</snippetWinQuote> #endregion #region Convert Quote to SalesOrder //<snippetConvertQuoteToSalesOrder> // Define columns to be retrieved after creating the order ColumnSet salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order ConvertQuoteToSalesOrderRequest convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; ConvertQuoteToSalesOrderResponse convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder salesOrder = (SalesOrder)convertQuoteResponse.Entity; _salesOrderId = salesOrder.Id; //</snippetConvertQuoteToSalesOrder> Console.WriteLine("Converted Quote to SalesOrder."); #endregion #region Cancel Sales Order //<snippetCancelSalesOrder> // Define columns to be retrieved after creating the order salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder closeSalesOrder = (SalesOrder)convertQuoteResponse.Entity; _closeSalesOrderId = closeSalesOrder.Id; CancelSalesOrderRequest cancelRequest = new CancelSalesOrderRequest() { OrderClose = new OrderClose() { SalesOrderId = closeSalesOrder.ToEntityReference(), Subject = "Close Sales Order " + DateTime.Now }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(cancelRequest); Console.WriteLine("Canceled sales order"); //</snippetCancelSalesOrder> #endregion #region Lock pricing on SalesOrder // Note: after converting a won quote to an order, the pricing of // the order is locked by default. //<snippetUpdateRequest> // Retrieve current price list ProductPriceLevel priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", salesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Update the price list priceListItem.Amount = new Money(30.0M); UpdateRequest updatePriceListItem = new UpdateRequest() { Target = priceListItem, }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); //</snippetUpdateRequest> // Retrieve the order SalesOrder updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetUnlockSalesOrderPricing> // Unlock the order pricing UnlockSalesOrderPricingRequest unlockOrderRequest = new UnlockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(unlockOrderRequest); //</snippetUnlockSalesOrderPricing> Console.WriteLine("Order pricing unlocked."); // Retrieve the order updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetLockSalesOrderPricing> // Relock the order pricing LockSalesOrderPricingRequest lockOrderRequest = new LockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(lockOrderRequest); //</snippetLockSalesOrderPricing> Console.WriteLine("Order pricing relocked."); #endregion //<snippetConvertSalesOrderToInvoice> #region Convert SalesOrder to Invoice // Define columns to be retrieved after creating the invoice ColumnSet invoiceColumns = new ColumnSet("invoiceid", "totalamount"); // Convert the order to an invoice ConvertSalesOrderToInvoiceRequest convertOrderRequest = new ConvertSalesOrderToInvoiceRequest() { SalesOrderId = _salesOrderId, ColumnSet = invoiceColumns }; ConvertSalesOrderToInvoiceResponse convertOrderResponse = (ConvertSalesOrderToInvoiceResponse)_serviceProxy.Execute(convertOrderRequest); Invoice invoice = (Invoice)convertOrderResponse.Entity; _invoiceId = invoice.Id; //</snippetConvertSalesOrderToInvoice> Console.WriteLine("Converted SalesOrder to Invoice."); #endregion #region Lock pricing on Invoice // Note: after converting a SalesOrder to Invoice, the pricing of // the Invoice is locked by default. // Retrieve current price list priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", invoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetUpdatePriceList> // Update the price list priceListItem.Amount = new Money(40.0M); updatePriceListItem = new UpdateRequest() { Target = priceListItem }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); //</snippetUpdatePriceList> //<snippetUnlockInvoicePricing> // Retrieve the invoice Invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Unlock the invoice pricing UnlockInvoicePricingRequest unlockInvoiceRequest = new UnlockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(unlockInvoiceRequest); Console.WriteLine("Invoice pricing unlocked."); //</snippetUnlockInvoicePricing> // Retrieve the invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetLockInvoicePricing> // Relock the invoice pricing LockInvoicePricingRequest lockInvoiceRequest = new LockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(lockInvoiceRequest); Console.WriteLine("Invoice pricing relocked."); //</snippetLockInvoicePricing> #endregion DeleteRequiredRecords(promptforDelete); } //</snippetProcessingQuotesAndSalesOrders1> } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>) { // You can handle an exception here or pass it back to the calling method. throw; } }
public void PerformTestSetup() { MessageName = "Win"; var quoteEntity = EntityFactory.CreateQuote(); var quoteClose = new Entity("quoteclose"); quoteClose["subject"] = "DummyQuoteClose"; quoteClose["quoteid"] = quoteEntity.ToEntityReference(); var setStateRequest = new SetStateRequest { EntityMoniker = quoteEntity.ToEntityReference(), State = new OptionSetValue(1), Status = new OptionSetValue(2) }; OrganizationService.Execute(setStateRequest); WinQuoteRequest = new WinQuoteRequest { QuoteClose = quoteClose, Status = new OptionSetValue(4), }; }
/// <summary> /// Change <c>Quote</c> status to <c>Won</c>. /// Please note that this action is required in order to convert a <c>Quote</c> into a <c>SalesOrder</c> with <see cref="ConvertToSalesOrder(Guid, string[])"/> method. /// <para> /// For more information look at https://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.winquoterequest(v=crm.7).aspx /// </para> /// </summary> /// <param name="id"><c>Quote</c> Id</param> /// <param name="status"><see cref="QuoteWonStatusCode"/> status code</param> /// <param name="customStatusCode">If you're using your custom statuscodes set this, otherwise you can set "0 (zero)" or null</param> /// <param name="quotecloseSubject"><c>QuoteClose</c> subject</param> /// <param name="quotecloseDescription"><c>QuoteClose</c> description</param> /// <param name="quotecloseActualEnd"><c>QuoteClose</c> actual end date</param> /// <returns><see cref="WinQuoteResponse"/></returns> public WinQuoteResponse Win(Guid id, QuoteWonStatusCode status, int customStatusCode = 0, string quotecloseSubject = "", string quotecloseDescription = "", DateTime?quotecloseActualEnd = null) { ExceptionThrow.IfGuidEmpty(id, "id"); int statusCode = (int)status; if (status == QuoteWonStatusCode.CustomStatusCode) { ExceptionThrow.IfNegative(customStatusCode, "customStatusCode"); statusCode = customStatusCode; } if (string.IsNullOrEmpty(quotecloseSubject)) { var quoteEntity = this.Get(id, "quotenumber"); quotecloseSubject = string.Format("Quote Close (Won) - {0}", quoteEntity.GetAttributeValue <string>("quotenumber")); } WinQuoteRequest request = new WinQuoteRequest() { QuoteClose = PrepareQuoteCloseEntity(id, quotecloseSubject, quotecloseDescription, quotecloseActualEnd), Status = new OptionSetValue(statusCode) }; return((WinQuoteResponse)this.OrganizationService.Execute(request)); }
protected override void ExecuteInternal(LocalWorkflowContext context) { var quoteReference = this.QuoteReference.Get(context.CodeActivityContext); WinQuoteRequest winQuoteRequest = new WinQuoteRequest(); Entity quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = quoteReference; quoteClose.Attributes["subject"] = "Quote Close" + DateTime.Now.ToString(); winQuoteRequest.QuoteClose = quoteClose; winQuoteRequest.Status = new OptionSetValue(-1); context.OrganizationService.Execute(winQuoteRequest); }
public void Update_DeliveryStatusTotalLine(Entity totalline, decimal preimage_net_quantity, decimal net_quantity) { decimal order_quantity = (decimal)totalline["bsd_quantity"]; decimal shipped_quantity = (decimal)totalline["bsd_shippedquantity"]; decimal new_shipped_quantity = shipped_quantity - preimage_net_quantity + net_quantity; Entity new_totalline = new Entity(totalline.LogicalName, totalline.Id); new_totalline["bsd_shippedquantity"] = new_shipped_quantity; decimal remaining_quantity = order_quantity - new_shipped_quantity; new_totalline["bsd_residualquantity"] = remaining_quantity; int status = 0; if (remaining_quantity == 0) { status = 861450003; // giao hết } else if (remaining_quantity == order_quantity) { status = 861450004; // không nhận } else { status = 861450002; // đã giao 1 phần } new_totalline["bsd_deliverystatus"] = new OptionSetValue(status); if (totalline.LogicalName == "quotedetail") { EntityReference quote_ref = (EntityReference)totalline["quoteid"]; myService.SetState(quote_ref.Id, quote_ref.LogicalName, 0, 1); // mở ra để udpate myService.Update(new_totalline); #region won quote myService.SetState(quote_ref.Id, quote_ref.LogicalName, 1, 2); WinQuoteRequest winQuoteRequest = new WinQuoteRequest(); Entity quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = new EntityReference("quote", new Guid(quote_ref.Id.ToString())); quoteClose.Attributes["subject"] = "Quote Close" + DateTime.Now.ToString(); winQuoteRequest.QuoteClose = quoteClose; winQuoteRequest.Status = new OptionSetValue(-1); myService.service.Execute(winQuoteRequest); #endregion } else { myService.Update(new_totalline); } }
protected override void ExecuteWorkflowLogic() { var winQuoteRecuest = new WinQuoteRequest() { Status = QuoteStatus.Get(Context.ExecutionContext), QuoteClose = new Entity("quoteclose") { ["subject"] = Subject.Get(Context.ExecutionContext), ["quoteid"] = Quote.Get(Context.ExecutionContext), ["actualend"] = CloseDate.Get(Context.ExecutionContext), ["description"] = Description.Get(Context.ExecutionContext) } }; Context.UserService.Execute(winQuoteRecuest); }
public WinQuoteResponse WinQuote(EntityReference entityReference) { var portal = PortalCrmConfigurationManager.CreatePortalContext(); var context = portal.ServiceContext; var quoteClose = new Entity("quoteclose"); quoteClose.Attributes["subject"] = "Quote Closed from Web " + DateTime.Now.ToString(CultureInfo.InvariantCulture); quoteClose.Attributes["quoteid"] = entityReference; var winQuoteRequest = new WinQuoteRequest() { QuoteClose = quoteClose, Status = new OptionSetValue(-1) }; var winQuoteResponse = (WinQuoteResponse)context.Execute(winQuoteRequest); return(winQuoteResponse); }
/***** * Currently unable to get this function working. * Soemthing about the WinQuoteRequest and CloseQuoteRequest does not fuction as expected * error: "cannot close the entity because it is not in the correct state" always occurs * ******************/ private static void ConvertQuoteToOrder(Microsoft.Xrm.Sdk.Client.OrganizationServiceContext context, Microsoft.Xrm.Sdk.Entity myQuote) { // Activate the quote SetStateRequest activateQuote = new SetStateRequest() { EntityMoniker = myQuote.ToEntityReference(), State = new OptionSetValue(1), Status = new OptionSetValue(2) }; context.Execute(activateQuote); //Console.WriteLine("Quote activated."); Guid quoteId = myQuote.GetAttributeValue <Guid>("quoteid"); var quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = myQuote.ToEntityReference(); quoteClose.Attributes["subject"] = "Won The Quote"; WinQuoteRequest winQuoteRequest = new WinQuoteRequest() { QuoteClose = quoteClose, Status = new OptionSetValue(-1) //2? -1?? }; var winQuoteResponse = (WinQuoteResponse)context.Execute(winQuoteRequest); ColumnSet salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); var convertOrderRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = quoteId, ColumnSet = salesOrderColumns }; var convertOrderResponse = (ConvertQuoteToSalesOrderResponse)context.Execute(convertOrderRequest); }
/// <summary> /// Closes a quote as won or lost, /// Revise is not supported via this method /// </summary> /// <param name="quoteId">ID of the quote to close</param> /// <param name="fieldList">List of fields that need to be updated</param> /// <param name="quoteStatusCode">Status id of the quote, must be greater then 3 but not 7</param> /// <param name="batchId">Optional: if set to a valid GUID, generated by the Create Batch Request Method, will assigned the request to the batch for later execution, on fail, runs the request immediately </param> /// <param name="cdsServiceClient">Connected CDS Service Client</param> /// <param name="bypassPluginExecution">Adds the bypass plugin behavior to this request. Note: this will only apply if the caller has the prvBypassPlugins permission to bypass plugins. If its attempted without the permission the request will fault.</param> /// <returns></returns> public static Guid CloseQuote(this CdsServiceClient cdsServiceClient, Guid quoteId, Dictionary <string, CdsDataTypeWrapper> fieldList, int quoteStatusCode = 3, Guid batchId = default(Guid), bool bypassPluginExecution = false) { cdsServiceClient.logEntry.ResetLastError(); // Reset Last Error if (cdsServiceClient._CdsService == null) { cdsServiceClient.logEntry.Log("Crm Service not initialized", TraceEventType.Error); return(Guid.Empty); } if (quoteId == Guid.Empty) { return(Guid.Empty); } if (quoteStatusCode < 3) { return(Guid.Empty); } Guid actId = Guid.Empty; Entity uEnt = new Entity("quoteclose"); AttributeCollection PropertyList = new AttributeCollection(); #region MapCode if (fieldList != null) { foreach (KeyValuePair <string, CdsDataTypeWrapper> field in fieldList) { cdsServiceClient.AddValueToPropertyList(field, PropertyList); } } // Add the key... // check to see if the key is in the import set already if (fieldList != null && !fieldList.ContainsKey("quoteid")) { PropertyList.Add(new KeyValuePair <string, object>("quoteid", quoteId)); } if (fieldList != null && fieldList.ContainsKey("activityid")) { actId = (Guid)fieldList["activityid"].Value; } else { actId = Guid.NewGuid(); uEnt.Id = actId; } #endregion uEnt.Attributes.AddRange(PropertyList.ToArray()); // 2 types of close supported... Won or Lost. if (quoteStatusCode == 4) { WinQuoteRequest req = new WinQuoteRequest(); req.QuoteClose = uEnt; req.Status = new OptionSetValue(quoteStatusCode); if (cdsServiceClient.AddRequestToBatch(batchId, req, "Calling Close Quote as Won", "Request to Close Quote as Won Queued", bypassPluginExecution)) { return(Guid.Empty); } WinQuoteResponse resp = (WinQuoteResponse)cdsServiceClient.CdsCommand_Execute(req, "Closing a Quote in CRM as Won", bypassPluginExecution); if (resp != null) { return(actId); } else { return(Guid.Empty); } } else { CloseQuoteRequest req = new CloseQuoteRequest(); req.QuoteClose = uEnt; req.Status = new OptionSetValue(quoteStatusCode); if (cdsServiceClient.AddRequestToBatch(batchId, req, "Calling Close Quote as Lost", "Request to Close Quote as Lost Queued", bypassPluginExecution)) { return(Guid.Empty); } CloseQuoteResponse resp = (CloseQuoteResponse)cdsServiceClient.CdsCommand_Execute(req, "Closing a Quote in CRM as Lost", bypassPluginExecution); if (resp != null) { return(actId); } else { return(Guid.Empty); } } }
public static void executeMultipleCloseQuote(EntityCollection entities, IOrganizationService service) { ExecuteMultipleRequest multipleRequest = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; foreach (Entity e in entities.Entities) { if (((OptionSetValue)e["statecode"]).Value == 3) { Entity quoteClose = new Entity("quoteclose"); quoteClose["quoteid"] = new EntityReference("quote", e.Id); quoteClose["subject"] = "Quote Close" + DateTime.Now.ToString(); WinQuoteRequest req = new WinQuoteRequest() { QuoteClose = quoteClose, Status = (OptionSetValue)e["statuscode"] }; multipleRequest.Requests.Add(req); } else if (((OptionSetValue)e["statecode"]).Value == 4) { Entity quoteClose = new Entity("quoteclose"); quoteClose["quoteid"] = new EntityReference("quote", e.Id); quoteClose["subject"] = "Quote Close" + DateTime.Now.ToString(); CloseQuoteRequest req = new CloseQuoteRequest() { QuoteClose = quoteClose, Status = (OptionSetValue)e["statuscode"] }; multipleRequest.Requests.Add(req); } } //This is how to get responses ExecuteMultipleResponse executeResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest); if (executeResponse.Results != null) { //Loop through responses foreach (ExecuteMultipleResponseItem responseItem in executeResponse.Responses) { if (responseItem.Response != null) { //Awesome, command completed as expected //success++; } else if (responseItem.Fault != null) { OrganizationRequest req = multipleRequest.Requests[responseItem.RequestIndex]; if (req.Parameters.Contains("Target")) { Entity entity = (Entity)req.Parameters["Target"]; GeneralHelper.WriteToText(entity.Id + ";QUOTECLOSE-" + responseItem.Fault.Message, @"C:\sahibinden\migration_" + entity.LogicalName + "_" + DateTime.Now.ToShortDateString() + ".txt"); } else { GeneralHelper.WriteToText(Guid.Empty + ";QUOTECLOSE-" + responseItem.Fault.Message, @"C:\sahibinden\migration_" + "noentity" + "_" + DateTime.Now.ToShortDateString() + ".txt"); } //Uh oh, error //error++; } else { //Error reporting error; } } } }
public void Execute(IServiceProvider serviceProvider) { context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext; factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); service = factory.CreateOrganizationService(context.UserId); try { //vinhlh 26-12-2017 bool connect_ax = getConfigdefaultconnectax(); if (connect_ax == false) { throw new Exception("Thiếu khai báo connect ax"); } #region KHai báo service AX NetTcpBinding binding = new NetTcpBinding(); //net.tcp://AOS_SERVICE_HOST/DynamicsAx/Services/AXConectorAIF binding.Name = "NetTcpBinding_BHS_BSD_CRMSERVICEAXService"; EndpointAddress endpoint = new EndpointAddress(new Uri("net.tcp://" + Utilites._port + "/DynamicsAx/Services/BHS_BSD_CRMSERVICEAXServiceGroup")); ServiceReferenceAIF.BHS_BSD_CRMSERVICEAXServiceClient client = new ServiceReferenceAIF.BHS_BSD_CRMSERVICEAXServiceClient(binding, endpoint); client.ClientCredentials.Windows.ClientCredential.Domain = Utilites._domain; client.ClientCredentials.Windows.ClientCredential.UserName = Utilites._userName; client.ClientCredentials.Windows.ClientCredential.Password = Utilites._passWord; ServiceReferenceAIF.CallContext contextService = new ServiceReferenceAIF.CallContext() { Company = Utilites._company }; #endregion #region vinhlh 21-11-2017 if (context.MessageName == "bsd_Action_CloseSubOrder") { #region bsd_Action_CloseSubOrder EntityReference rf; EntityReference target = (EntityReference)context.InputParameters["Target"]; Entity suborder = service.Retrieve(target.LogicalName, target.Id, new ColumnSet(true)); if (suborder.HasValue("bsd_type")) { if (((OptionSetValue)suborder["bsd_type"]).Value == 861450001) //861450001 Quote { #region Cập nhật lại số lượng còn lại Quote bsd_quote if (suborder.HasValue("bsd_quote")) { rf = (EntityReference)suborder["bsd_quote"]; EntityCollection lst_suborderProduct = getsubOrderProduct(suborder.Id); if (lst_suborderProduct.Entities.Any()) { this.SetState(rf.Id, rf.LogicalName, 0, 1); foreach (var suborderProduct in lst_suborderProduct.Entities) { EntityReference rf_product = (EntityReference)suborderProduct["bsd_product"]; Entity qouteProduct = getQuoteProduct(rf.Id, rf_product.Id); Entity qouteProduct_Update = new Entity(qouteProduct.LogicalName, qouteProduct.Id); decimal bsd_remainingquantity = 0m; decimal bsd_shipquantity = 0m; decimal bsd_shippedquantity = 0m; decimal bsd_suborderquantity = 0m; if (qouteProduct.HasValue("bsd_remainingquantity")) { bsd_remainingquantity = (decimal)qouteProduct["bsd_remainingquantity"]; } if (qouteProduct.HasValue("bsd_suborderquantity")) { bsd_suborderquantity = (decimal)qouteProduct["bsd_suborderquantity"]; } if (suborderProduct.HasValue("bsd_shipquantity")) { bsd_shipquantity = (decimal)suborderProduct["bsd_shipquantity"]; } if (suborderProduct.HasValue("bsd_shippedquantity")) { bsd_shippedquantity = (decimal)suborderProduct["bsd_shippedquantity"]; } // throw new Exception((bsd_remainingquantity + (bsd_shipquantity - bsd_shippedquantity)).ToString()); qouteProduct_Update["bsd_remainingquantity"] = bsd_remainingquantity + (bsd_shipquantity - bsd_shippedquantity); qouteProduct_Update["bsd_suborderquantity"] = bsd_suborderquantity - (bsd_shipquantity - bsd_shippedquantity); // qouteProduct_Update["bsd_remainingquantity"] = 0m; service.Update(qouteProduct_Update); } #region Won Quote this.SetState(rf.Id, rf.LogicalName, 1, 2); WinQuoteRequest winQuoteRequest = new WinQuoteRequest(); Entity quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = new EntityReference("quote", rf.Id); quoteClose.Attributes["subject"] = "Quote Close" + DateTime.Now.ToString(); winQuoteRequest.QuoteClose = quoteClose; winQuoteRequest.Status = new OptionSetValue(-1); service.Execute(winQuoteRequest); #endregion } } #endregion } else if (((OptionSetValue)suborder["bsd_type"]).Value == 861450002)//861450002 Order { #region Cập nhật lại số lượng còn lại Sale Contract if (suborder.HasValue("bsd_order")) { rf = (EntityReference)suborder["bsd_order"]; EntityCollection lst_suborderProduct = getsubOrderProduct(suborder.Id); if (lst_suborderProduct.Entities.Any()) { foreach (var suborderProduct in lst_suborderProduct.Entities) { EntityReference rf_product = (EntityReference)suborderProduct["bsd_product"]; Entity orderProduct = getOrderProduct(rf.Id, rf_product.Id); Entity orderProduct_Update = new Entity(orderProduct.LogicalName, orderProduct.Id); decimal bsd_remainingquantity = 0m; decimal bsd_shipquantity = 0m; decimal bsd_shippedquantity = 0m; decimal bsd_suborderquantity = 0m; if (orderProduct.HasValue("bsd_remainingquantity")) { bsd_remainingquantity = (decimal)orderProduct["bsd_remainingquantity"]; } if (orderProduct.HasValue("bsd_suborderquantity")) { bsd_suborderquantity = (decimal)orderProduct["bsd_suborderquantity"]; } if (suborderProduct.HasValue("bsd_shipquantity")) { bsd_shipquantity = (decimal)suborderProduct["bsd_shipquantity"]; } if (suborderProduct.HasValue("bsd_shippedquantity")) { bsd_shippedquantity = (decimal)suborderProduct["bsd_shippedquantity"]; } orderProduct_Update["bsd_remainingquantity"] = bsd_remainingquantity + (bsd_shipquantity - bsd_shippedquantity); orderProduct_Update["bsd_suborderquantity"] = bsd_suborderquantity - (bsd_shipquantity - bsd_shippedquantity); // orderProduct_Update["bsd_remainingquantity"] = 0m; service.Update(orderProduct_Update); } } } #endregion } } #region Cập nhật trạng thái suborder thành Closed Entity suborder_Update = new Entity(suborder.LogicalName, suborder.Id); suborder_Update["statuscode"] = new OptionSetValue(861450008); service.Update(suborder_Update); //throw new Exception("okie"); #endregion #region 27-12-2017 call service AX if (suborder.Contains("bsd_suborderax") && suborder["bsd_suborderax"] != null) { string s_Result = client.BHS_CancelSalesOrder(contextService, suborder["bsd_suborderax"].ToString().Trim()); if (s_Result != "Success") { throw new Exception("AX " + s_Result); } } #endregion #endregion } else if (context.MessageName == "bsd_Action_CloseDeliverySchedule") { #region bsd_Action_CloseDeliverySchedule EntityReference target = (EntityReference)context.InputParameters["Target"]; Entity deliverySchedule = service.Retrieve(target.LogicalName, target.Id, new ColumnSet(true)); EntityCollection lst_requestDelivery = getRequestDelivery(deliverySchedule.Id); if (lst_requestDelivery.Entities.Any()) { foreach (var requestDelivery in lst_requestDelivery.Entities) { EntityCollection lst_deliveryNote = getDeliveryNote(requestDelivery.Id); if (lst_deliveryNote.Entities.Any()) { foreach (var deliveryNote in lst_deliveryNote.Entities) { #region Cập nhật lại Delivery Note trạng thái thành fullfil Entity deliveryNote_Update = new Entity(deliveryNote.LogicalName, deliveryNote.Id); deliveryNote_Update["bsd_status"] = new OptionSetValue(861450002); service.Update(deliveryNote_Update); #endregion } } } } #region Cập nhật lại delivery Schedule trạng thái thành fullfil Entity deliverySchedule_Update = new Entity(deliverySchedule.LogicalName, deliverySchedule.Id); deliverySchedule_Update["bsd_status"] = new OptionSetValue(861450003); service.Update(deliverySchedule_Update); #endregion #endregion } #endregion } catch (Exception ex) { throw new Exception(ex.Message); } }
[STAThread] // Required to support the interactive login experience static void Main(string[] args) { CrmServiceClient service = null; try { service = SampleHelpers.Connect("Connect"); if (service.IsReady) { // Create any entity records that the demonstration code requires SetUpSample(service); #region Demonstrate // TODO Add demonstration code here #region Create Opportunities // Create an opportunity var crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _opportunityId = _serviceProxy.Create(crmOpportunity); crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Another Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _loseOpportunityId = _serviceProxy.Create(crmOpportunity); Console.WriteLine("Opportunities created."); #endregion #region Win Opportunity // Close the opportunity as won var winOppRequest = new WinOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _opportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Won) }; _serviceProxy.Execute(winOppRequest); Console.WriteLine("Opportunity closed as Won."); #endregion #region Lose Opportunity var loseOppRequest = new LoseOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _loseOpportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Canceled) }; _serviceProxy.Execute(loseOppRequest); Console.WriteLine("Opportunity closed as Lost."); #endregion #region Convert Opportunity to a Quote // Convert the opportunity to a quote var genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; var genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote quote = genQuoteFromOppResponse.Entity.ToEntity <Quote>(); _quoteId = quote.Id; Console.WriteLine("Quote generated from the Opportunity."); #endregion #region Close Quote // convert the opportunity to a quote genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote closeQuote = genQuoteFromOppResponse.Entity.ToEntity <Quote>(); _closeQuoteId = closeQuote.Id; // Activate the quote SetStateRequest activateQuote = new SetStateRequest() { EntityMoniker = closeQuote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); // Close the quote CloseQuoteRequest closeQuoteRequest = new CloseQuoteRequest() { QuoteClose = new QuoteClose() { QuoteId = closeQuote.ToEntityReference(), Subject = "Quote Close " + DateTime.Now.ToString() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(closeQuoteRequest); Console.WriteLine("Quote Closed"); #endregion #region Create Quote's Product // Set the quote's product QuoteDetail quoteDetail = new QuoteDetail() { ProductId = new EntityReference(Product.EntityLogicalName, _productId), Quantity = 1, QuoteId = quote.ToEntityReference(), UoMId = new EntityReference(UoM.EntityLogicalName, _defaultUnitId) }; _quoteDetailId = _serviceProxy.Create(quoteDetail); Console.WriteLine("Quote Product created."); // Activate the quote activateQuote = new SetStateRequest() { EntityMoniker = quote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); Console.WriteLine("Quote activated."); // Mark the quote as won // Note: this is necessary in order to convert a quote into a // SalesOrder. WinQuoteRequest winQuoteRequest = new WinQuoteRequest() { QuoteClose = new QuoteClose() { Subject = "Quote Close" + DateTime.Now.ToString(), QuoteId = quote.ToEntityReference() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(winQuoteRequest); Console.WriteLine("Quote won."); #endregion #region Convert Quote to SalesOrder // Define columns to be retrieved after creating the order ColumnSet salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order ConvertQuoteToSalesOrderRequest convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; ConvertQuoteToSalesOrderResponse convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder salesOrder = (SalesOrder)convertQuoteResponse.Entity; _salesOrderId = salesOrder.Id; Console.WriteLine("Converted Quote to SalesOrder."); #endregion #region Cancel Sales Order // Define columns to be retrieved after creating the order salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder closeSalesOrder = (SalesOrder)convertQuoteResponse.Entity; _closeSalesOrderId = closeSalesOrder.Id; CancelSalesOrderRequest cancelRequest = new CancelSalesOrderRequest() { OrderClose = new OrderClose() { SalesOrderId = closeSalesOrder.ToEntityReference(), Subject = "Close Sales Order " + DateTime.Now }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(cancelRequest); Console.WriteLine("Canceled sales order"); #endregion #region Lock pricing on SalesOrder // Note: after converting a won quote to an order, the pricing of // the order is locked by default. // Retrieve current price list ProductPriceLevel priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", salesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Update the price list priceListItem.Amount = new Money(30.0M); UpdateRequest updatePriceListItem = new UpdateRequest() { Target = priceListItem, }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); // Retrieve the order SalesOrder updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Unlock the order pricing UnlockSalesOrderPricingRequest unlockOrderRequest = new UnlockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(unlockOrderRequest); Console.WriteLine("Order pricing unlocked."); // Retrieve the order updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Relock the order pricing LockSalesOrderPricingRequest lockOrderRequest = new LockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(lockOrderRequest); Console.WriteLine("Order pricing relocked."); #endregion #region Convert SalesOrder to Invoice // Define columns to be retrieved after creating the invoice ColumnSet invoiceColumns = new ColumnSet("invoiceid", "totalamount"); // Convert the order to an invoice ConvertSalesOrderToInvoiceRequest convertOrderRequest = new ConvertSalesOrderToInvoiceRequest() { SalesOrderId = _salesOrderId, ColumnSet = invoiceColumns }; ConvertSalesOrderToInvoiceResponse convertOrderResponse = (ConvertSalesOrderToInvoiceResponse)_serviceProxy.Execute(convertOrderRequest); Invoice invoice = (Invoice)convertOrderResponse.Entity; _invoiceId = invoice.Id; Console.WriteLine("Converted SalesOrder to Invoice."); #endregion #region Lock pricing on Invoice // Note: after converting a SalesOrder to Invoice, the pricing of // the Invoice is locked by default. // Retrieve current price list priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", invoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Update the price list priceListItem.Amount = new Money(40.0M); updatePriceListItem = new UpdateRequest() { Target = priceListItem }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); // Retrieve the invoice Invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Unlock the invoice pricing UnlockInvoicePricingRequest unlockInvoiceRequest = new UnlockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(unlockInvoiceRequest); Console.WriteLine("Invoice pricing unlocked."); // Retrieve the invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Relock the invoice pricing LockInvoicePricingRequest lockInvoiceRequest = new LockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(lockInvoiceRequest); Console.WriteLine("Invoice pricing relocked."); #endregion #endregion Demonstrate } else { const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Common Data Service"; if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR)) { Console.WriteLine("Check the connection string values in cds/App.config."); throw new Exception(service.LastCrmError); } else { throw service.LastCrmException; } } } catch (Exception ex) { SampleHelpers.HandleException(ex); } finally { if (service != null) { service.Dispose(); } Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } }
/// <summary> /// This method first connects to the Organization service. Afterwards, a /// quote is created. This quote is then converted to an order, and the pricing /// is unlocked and relocked. This is followed by the order being converted /// to an invoice, and the pricing is locked then unlocked. /// </summary> /// <param name="serverConfig">Contains server connection information.</param> /// <param name="promptforDelete">When True, the user will be prompted to delete all /// created entities.</param> public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { try { //<snippetProcessingQuotesAndSalesOrders1> // Connect to the Organization service. // The using statement assures that the service proxy will be properly disposed. using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri, serverConfig.Credentials, serverConfig.DeviceCredentials)) { // This statement is required to enable early-bound type support. _serviceProxy.EnableProxyTypes(); CreateRequiredRecords(); #region Create Opportunities // Create an opportunity var crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _opportunityId = _serviceProxy.Create(crmOpportunity); crmOpportunity = new Opportunity { CustomerId = new EntityReference(Account.EntityLogicalName, _accountId), Name = "Another Sample", PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, _priceListId) }; _loseOpportunityId = _serviceProxy.Create(crmOpportunity); Console.WriteLine("Opportunities created."); #endregion #region Win Opportunity //<snippetWinOpportunity> // Close the opportunity as won var winOppRequest = new WinOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _opportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Won), }; _serviceProxy.Execute(winOppRequest); Console.WriteLine("Opportunity closed as Won."); //</snippetWinOpportunity> #endregion #region Lose Opportunity //<snippetLoseOpportunity> var loseOppRequest = new LoseOpportunityRequest { OpportunityClose = new OpportunityClose { OpportunityId = new EntityReference (Opportunity.EntityLogicalName, _loseOpportunityId) }, Status = new OptionSetValue((int)opportunity_statuscode.Canceled) }; _serviceProxy.Execute(loseOppRequest); Console.WriteLine("Opportunity closed as Lost."); //</snippetLoseOpportunity> #endregion #region Convert Opportunity to a Quote //<snippetGenerateQuoteFromOpportunity> // Convert the opportunity to a quote var genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; var genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote quote = genQuoteFromOppResponse.Entity.ToEntity <Quote>(); _quoteId = quote.Id; Console.WriteLine("Quote generated from the Opportunity."); //</snippetGenerateQuoteFromOpportunity> #endregion #region Close Quote //<snippetCloseQuote> // convert the opportunity to a quote genQuoteFromOppRequest = new GenerateQuoteFromOpportunityRequest { OpportunityId = _opportunityId, ColumnSet = new ColumnSet("quoteid", "name") }; genQuoteFromOppResponse = (GenerateQuoteFromOpportunityResponse) _serviceProxy.Execute(genQuoteFromOppRequest); Quote closeQuote = genQuoteFromOppResponse.Entity.ToEntity <Quote>(); _closeQuoteId = closeQuote.Id; // Activate the quote SetStateRequest activateQuote = new SetStateRequest() { EntityMoniker = closeQuote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); // Close the quote CloseQuoteRequest closeQuoteRequest = new CloseQuoteRequest() { QuoteClose = new QuoteClose() { QuoteId = closeQuote.ToEntityReference(), Subject = "Quote Close " + DateTime.Now.ToString() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(closeQuoteRequest); Console.WriteLine("Quote Closed"); //</snippetCloseQuote> #endregion #region Create Quote's Product // Set the quote's product QuoteDetail quoteDetail = new QuoteDetail() { ProductId = new EntityReference(Product.EntityLogicalName, _productId), Quantity = 1, QuoteId = quote.ToEntityReference(), UoMId = new EntityReference(UoM.EntityLogicalName, _defaultUnitId) }; _quoteDetailId = _serviceProxy.Create(quoteDetail); Console.WriteLine("Quote Product created."); // Activate the quote activateQuote = new SetStateRequest() { EntityMoniker = quote.ToEntityReference(), State = new OptionSetValue((int)QuoteState.Active), Status = new OptionSetValue((int)quote_statuscode.InProgress) }; _serviceProxy.Execute(activateQuote); Console.WriteLine("Quote activated."); //<snippetWinQuote> // Mark the quote as won // Note: this is necessary in order to convert a quote into a // SalesOrder. WinQuoteRequest winQuoteRequest = new WinQuoteRequest() { QuoteClose = new QuoteClose() { Subject = "Quote Close" + DateTime.Now.ToString(), QuoteId = quote.ToEntityReference() }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(winQuoteRequest); Console.WriteLine("Quote won."); //</snippetWinQuote> #endregion #region Convert Quote to SalesOrder //<snippetConvertQuoteToSalesOrder> // Define columns to be retrieved after creating the order ColumnSet salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order ConvertQuoteToSalesOrderRequest convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; ConvertQuoteToSalesOrderResponse convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder salesOrder = (SalesOrder)convertQuoteResponse.Entity; _salesOrderId = salesOrder.Id; //</snippetConvertQuoteToSalesOrder> Console.WriteLine("Converted Quote to SalesOrder."); #endregion #region Cancel Sales Order //<snippetCancelSalesOrder> // Define columns to be retrieved after creating the order salesOrderColumns = new ColumnSet("salesorderid", "totalamount"); // Convert the quote to a sales order convertQuoteRequest = new ConvertQuoteToSalesOrderRequest() { QuoteId = _quoteId, ColumnSet = salesOrderColumns }; convertQuoteResponse = (ConvertQuoteToSalesOrderResponse)_serviceProxy.Execute(convertQuoteRequest); SalesOrder closeSalesOrder = (SalesOrder)convertQuoteResponse.Entity; _closeSalesOrderId = closeSalesOrder.Id; CancelSalesOrderRequest cancelRequest = new CancelSalesOrderRequest() { OrderClose = new OrderClose() { SalesOrderId = closeSalesOrder.ToEntityReference(), Subject = "Close Sales Order " + DateTime.Now }, Status = new OptionSetValue(-1) }; _serviceProxy.Execute(cancelRequest); Console.WriteLine("Canceled sales order"); //</snippetCancelSalesOrder> #endregion #region Lock pricing on SalesOrder // Note: after converting a won quote to an order, the pricing of // the order is locked by default. //<snippetUpdateRequest> // Retrieve current price list ProductPriceLevel priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", salesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Update the price list priceListItem.Amount = new Money(30.0M); UpdateRequest updatePriceListItem = new UpdateRequest() { Target = priceListItem, }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); //</snippetUpdateRequest> // Retrieve the order SalesOrder updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetUnlockSalesOrderPricing> // Unlock the order pricing UnlockSalesOrderPricingRequest unlockOrderRequest = new UnlockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(unlockOrderRequest); //</snippetUnlockSalesOrderPricing> Console.WriteLine("Order pricing unlocked."); // Retrieve the order updatedSalesOrder = (SalesOrder)_serviceProxy.Retrieve( SalesOrder.EntityLogicalName, _salesOrderId, new ColumnSet("salesorderid", "totalamount") ); Console.WriteLine("Updated order retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current order total: {0}", updatedSalesOrder.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetLockSalesOrderPricing> // Relock the order pricing LockSalesOrderPricingRequest lockOrderRequest = new LockSalesOrderPricingRequest() { SalesOrderId = _salesOrderId }; _serviceProxy.Execute(lockOrderRequest); //</snippetLockSalesOrderPricing> Console.WriteLine("Order pricing relocked."); #endregion //<snippetConvertSalesOrderToInvoice> #region Convert SalesOrder to Invoice // Define columns to be retrieved after creating the invoice ColumnSet invoiceColumns = new ColumnSet("invoiceid", "totalamount"); // Convert the order to an invoice ConvertSalesOrderToInvoiceRequest convertOrderRequest = new ConvertSalesOrderToInvoiceRequest() { SalesOrderId = _salesOrderId, ColumnSet = invoiceColumns }; ConvertSalesOrderToInvoiceResponse convertOrderResponse = (ConvertSalesOrderToInvoiceResponse)_serviceProxy.Execute(convertOrderRequest); Invoice invoice = (Invoice)convertOrderResponse.Entity; _invoiceId = invoice.Id; //</snippetConvertSalesOrderToInvoice> Console.WriteLine("Converted SalesOrder to Invoice."); #endregion #region Lock pricing on Invoice // Note: after converting a SalesOrder to Invoice, the pricing of // the Invoice is locked by default. // Retrieve current price list priceListItem = (ProductPriceLevel)_serviceProxy.Retrieve( ProductPriceLevel.EntityLogicalName, _priceListItemId, new ColumnSet("productpricelevelid", "amount") ); Console.WriteLine("Current price list retrieved."); Console.WriteLine(); Console.WriteLine("Details before lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", invoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetUpdatePriceList> // Update the price list priceListItem.Amount = new Money(40.0M); updatePriceListItem = new UpdateRequest() { Target = priceListItem }; _serviceProxy.Execute(updatePriceListItem); Console.WriteLine("Price list updated."); //</snippetUpdatePriceList> //<snippetUnlockInvoicePricing> // Retrieve the invoice Invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after lock and update:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); // Unlock the invoice pricing UnlockInvoicePricingRequest unlockInvoiceRequest = new UnlockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(unlockInvoiceRequest); Console.WriteLine("Invoice pricing unlocked."); //</snippetUnlockInvoicePricing> // Retrieve the invoice updatedInvoice = (Invoice)_serviceProxy.Retrieve( Invoice.EntityLogicalName, _invoiceId, new ColumnSet("invoiceid", "totalamount") ); Console.WriteLine("Updated invoice retrieved."); Console.WriteLine(); Console.WriteLine("Details after update and unlock:"); Console.WriteLine("----------------"); Console.WriteLine("Current invoice total: {0}", updatedInvoice.TotalAmount.Value); Console.WriteLine("Current price per item: {0}", priceListItem.Amount.Value); Console.WriteLine("</End of Listing>"); Console.WriteLine(); //<snippetLockInvoicePricing> // Relock the invoice pricing LockInvoicePricingRequest lockInvoiceRequest = new LockInvoicePricingRequest() { InvoiceId = _invoiceId }; _serviceProxy.Execute(lockInvoiceRequest); Console.WriteLine("Invoice pricing relocked."); //</snippetLockInvoicePricing> #endregion DeleteRequiredRecords(promptforDelete); } //</snippetProcessingQuotesAndSalesOrders1> } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ) { // You can handle an exception here or pass it back to the calling method. throw; } }
public void Update_StatusOrderAndQuote(Entity suborder_product, decimal net_quantity, decimal preimage_net_quantity, decimal net_quantityorder, decimal preimage_quantityorder, decimal net_quantityappendix, decimal preimage_quantityappendix) { Entity suborder = myService.service.Retrieve("bsd_suborder", ((EntityReference)suborder_product["bsd_suborder"]).Id, new ColumnSet(true)); int type = ((OptionSetValue)suborder["bsd_type"]).Value; bool multipleaddress = (bool)suborder["bsd_multipleaddress"]; #region quote if (type == 861450001) // quote { SuborderService suborderService = new SuborderService(myService); Entity quotedetail = suborderService.getQuoteDetailFromSuborderProduct(suborder_product, 2); Entity quote = myService.service.Retrieve("quote", ((EntityReference)quotedetail["quoteid"]).Id, new ColumnSet("bsd_havequantity")); bool have_quantity = (bool)quote["bsd_havequantity"]; EntityReference quote_ref = (EntityReference)quotedetail["quoteid"]; myService.SetState(quote_ref.Id, quote_ref.LogicalName, 0, 1); // mở ra để udpate decimal order_quantity = (multipleaddress && have_quantity == false) ? (decimal)quotedetail["bsd_suborderquantity"] : (decimal)quotedetail["quantity"]; decimal shipped_quantity = (decimal)quotedetail["bsd_shippedquantity"]; decimal new_shipped_quantity = shipped_quantity - preimage_net_quantity + net_quantity; Entity new_quote_product = new Entity(quotedetail.LogicalName, quotedetail.Id); new_quote_product["bsd_shippedquantity"] = new_shipped_quantity; decimal remaining_quantity = order_quantity - new_shipped_quantity; new_quote_product["bsd_residualquantity"] = remaining_quantity; int status = 0; if (remaining_quantity == 0) { status = 861450003; // giao hết } else if (remaining_quantity == order_quantity) { status = 861450004; // không nhận } else { status = 861450002; // đã giao 1 phần } new_quote_product["bsd_deliverystatus"] = new OptionSetValue(status); myService.Update(new_quote_product); #region won quote myService.SetState(quote_ref.Id, quote_ref.LogicalName, 1, 2); WinQuoteRequest winQuoteRequest = new WinQuoteRequest(); Entity quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = new EntityReference("quote", new Guid(quote_ref.Id.ToString())); quoteClose.Attributes["subject"] = "Quote Close" + DateTime.Now.ToString(); winQuoteRequest.QuoteClose = quoteClose; winQuoteRequest.Status = new OptionSetValue(-1); myService.service.Execute(winQuoteRequest); #endregion if (have_quantity == false) { SuborderService subService = new SuborderService(myService); EntityReference product_ref = (EntityReference)quotedetail["productid"]; Entity totalline = subService.Get_LineTotal_QuoteProduct_Quantity(product_ref.Id, quote_ref.Id); Update_DeliveryStatusTotalLine(totalline, preimage_net_quantity, net_quantity); } } #endregion #region appendix contract else if (type == 861450002 && suborder_product.HasValue("bsd_appendixcontract"))//huy: trường hợp có phụ lục { Entity appendixcontract = myService.service.Retrieve("bsd_appendixcontract", ((EntityReference)suborder_product["bsd_appendixcontract"]).Id, new ColumnSet(true)); SuborderService suborderService = new SuborderService(myService); Entity salesorderdetail = suborderService.getSalesorderDetailFromSuborderProduct(suborder_product, 2); Entity salesorder = myService.service.Retrieve("salesorder", ((EntityReference)salesorderdetail["salesorderid"]).Id, new ColumnSet("bsd_havequantity")); Entity appendixdetail = suborderService.getAppendixContractdetailFromSuborderProduct(suborder_product, 2); bool have_quantity = (bool)salesorder["bsd_havequantity"]; decimal order_quantity = (multipleaddress && have_quantity == false) ? (decimal)salesorderdetail["bsd_suborderquantity"] : (decimal)salesorderdetail["quantity"]; decimal appendix_quantity = (multipleaddress && have_quantity == false) ? (decimal)appendixdetail["bsd_suborderquantityappendix"] : (decimal)appendixdetail["bsd_newquantity"]; decimal shipped_quantity = (decimal)salesorderdetail["bsd_shippedquantity"]; decimal shipped_quantity_appendix = appendixdetail.HasValue("bsd_shippedquantityappendix") ? (decimal)appendixdetail["bsd_shippedquantityappendix"] : 0; decimal new_shipped_quantity = shipped_quantity - preimage_quantityorder + net_quantityorder; decimal new_shipped_quantity_appendix = shipped_quantity_appendix - preimage_quantityappendix + net_quantityappendix; #region cập nhật ở hdkt Entity new_order_product = new Entity(salesorderdetail.LogicalName, salesorderdetail.Id); new_order_product["bsd_shippedquantity"] = new_shipped_quantity; decimal remaining_quantity = order_quantity - new_shipped_quantity; new_order_product["bsd_residualquantity"] = remaining_quantity; int status = 0; if (remaining_quantity == 0) { status = 861450003; // giao hết } else if (remaining_quantity == order_quantity) { status = 861450004; // không nhận } else { status = 861450002; // đã giao 1 phần } new_order_product["bsd_deliverystatus"] = new OptionSetValue(status); myService.Update(new_order_product); #endregion #region cập nhật ở phụ lục Entity new_appendix_product = new Entity(appendixdetail.LogicalName, appendixdetail.Id); new_appendix_product["bsd_shippedquantityappendix"] = new_shipped_quantity_appendix; decimal remaining_quantity_appendix = appendix_quantity - new_shipped_quantity_appendix; new_appendix_product["bsd_residualquantity"] = remaining_quantity_appendix; int status_appendix = 0; if (remaining_quantity_appendix == 0) { status_appendix = 861450003; // giao hết } else if (remaining_quantity_appendix == appendix_quantity) { status_appendix = 861450004; // không nhận } else { status_appendix = 861450002; // đã giao 1 phần } new_appendix_product["bsd_deliverystatus"] = new OptionSetValue(status_appendix); myService.Update(new_appendix_product); #endregion if (have_quantity == false) { SuborderService subService = new SuborderService(myService); EntityReference order_product_ref = (EntityReference)salesorderdetail["productid"]; EntityReference order_ref = (EntityReference)salesorderdetail["salesorderid"]; Entity totalline = subService.Get_LineTotal_OrderProduct_Quantity(order_product_ref.Id, order_ref.Id); Update_DeliveryStatusTotalLine(totalline, preimage_quantityorder, net_quantityorder); } } #endregion #region order else if (type == 861450002)// order { SuborderService suborderService = new SuborderService(myService); Entity salesorderdetail = suborderService.getSalesorderDetailFromSuborderProduct(suborder_product, 2); Entity salesorder = myService.service.Retrieve("salesorder", ((EntityReference)salesorderdetail["salesorderid"]).Id, new ColumnSet("bsd_havequantity")); bool have_quantity = (bool)salesorder["bsd_havequantity"]; decimal order_quantity = (multipleaddress && have_quantity == false) ? (decimal)salesorderdetail["bsd_suborderquantity"] : (decimal)salesorderdetail["quantity"]; decimal shipped_quantity = (decimal)salesorderdetail["bsd_shippedquantity"]; decimal new_shipped_quantity = shipped_quantity - preimage_net_quantity + net_quantity; Entity new_order_product = new Entity(salesorderdetail.LogicalName, salesorderdetail.Id); new_order_product["bsd_shippedquantity"] = new_shipped_quantity; decimal remaining_quantity = order_quantity - new_shipped_quantity; new_order_product["bsd_residualquantity"] = remaining_quantity; int status = 0; if (remaining_quantity == 0) { status = 861450003; // giao hết } else if (remaining_quantity == order_quantity) { status = 861450004; // không nhận } else { status = 861450002; // đã giao 1 phần } new_order_product["bsd_deliverystatus"] = new OptionSetValue(status); myService.Update(new_order_product); if (have_quantity == false) { SuborderService subService = new SuborderService(myService); EntityReference product_ref = (EntityReference)salesorderdetail["productid"]; EntityReference order_ref = (EntityReference)salesorderdetail["salesorderid"]; Entity totalline = subService.Get_LineTotal_OrderProduct_Quantity(product_ref.Id, order_ref.Id); Update_DeliveryStatusTotalLine(totalline, preimage_net_quantity, net_quantity); } } #endregion }
public void Execute(IServiceProvider serviceProvider) { myService = new MyService(serviceProvider); #region Update if (myService.context.MessageName == "Update") { myService.StartService(); Entity target = myService.getTarget(); if (target.HasValue("bsd_skipplugin") && (bool)target["bsd_skipplugin"]) { return; } Entity suborder = myService.service.Retrieve(target.LogicalName, target.Id, new ColumnSet(true)); if (target.HasValue("statecode")) { int statecode = ((OptionSetValue)target["statecode"]).Value; if (statecode == 1) { #region Nếu có Status và nó là từ quote hoặc order if (suborder.HasValue("bsd_quote") || suborder.HasValue("bsd_order")) { Service.SuborderService subService = new Service.SuborderService(myService); EntityCollection list_suborderproduct = myService.RetrieveOneCondition("bsd_suborderproduct", "bsd_suborder", target.Id); foreach (var suborder_product in list_suborderproduct.Entities) { decimal ship_quantity = (decimal)suborder_product["bsd_shipquantity"]; if (suborder.HasValue("bsd_quote")) { Entity quotedetail = subService.getQuoteDetailFromSuborderProduct(suborder_product, 2); Entity quote = myService.service.Retrieve("quote", ((EntityReference)quotedetail["quoteid"]).Id, new ColumnSet(true)); bool multiple_address = (bool)quote["bsd_multipleaddress"]; bool have_quantity = (bool)quote["bsd_havequantity"]; if (multiple_address == false || (multiple_address == true && have_quantity == true)) { decimal quantity = (decimal)quotedetail["quantity"]; decimal old_suborder_quantity = (decimal)quotedetail["bsd_suborderquantity"]; decimal remaining_quantity = (decimal)quotedetail["bsd_remainingquantity"]; decimal new_suborder_quantity = old_suborder_quantity - ship_quantity; decimal new_remaining_quantity = quantity - new_suborder_quantity; #region Cập nhật lại quantity EntityReference quote_ref = (EntityReference)suborder["bsd_quote"]; myService.SetState(quote_ref.Id, quote_ref.LogicalName, 0, 1); Entity new_quotedetail = new Entity(quotedetail.LogicalName, quotedetail.Id); new_quotedetail["bsd_suborderquantity"] = new_suborder_quantity; new_quotedetail["bsd_remainingquantity"] = new_remaining_quantity; myService.Update(new_quotedetail); #region won quote myService.SetState(quote_ref.Id, quote_ref.LogicalName, 1, 2); WinQuoteRequest winQuoteRequest = new WinQuoteRequest(); Entity quoteClose = new Entity("quoteclose"); quoteClose.Attributes["quoteid"] = new EntityReference("quote", new Guid(quote_ref.Id.ToString())); quoteClose.Attributes["subject"] = "Quote Close" + DateTime.Now.ToString(); winQuoteRequest.QuoteClose = quoteClose; winQuoteRequest.Status = new OptionSetValue(-1); myService.service.Execute(winQuoteRequest); #endregion #endregion } else { // cancel thì trừ đi cũng giống như xóa subService.DeleteSuborderProduct(suborder_product); } } else if (suborder.HasValue("bsd_order") && !suborder.HasValue("bsd_appendixcontract"))//không có phụ lục, nếu có thì chạy qua code Huy { Entity salesorderdetail = subService.getSalesorderDetailFromSuborderProduct(suborder_product, 2); Entity order = myService.service.Retrieve("salesorder", ((EntityReference)salesorderdetail["salesorderid"]).Id, new ColumnSet(true)); bool multiple_address = (bool)order["bsd_multipleaddress"]; bool have_quantity = (bool)order["bsd_havequantity"]; if (multiple_address == false || (multiple_address == true && have_quantity == true)) { decimal quantity = (decimal)salesorderdetail["quantity"]; decimal old_suborder_quantity = (decimal)salesorderdetail["bsd_suborderquantity"]; decimal remaining_quantity = (decimal)salesorderdetail["bsd_remainingquantity"]; decimal new_suborder_quantity = old_suborder_quantity - ship_quantity; decimal new_remaining_quantity = quantity - new_suborder_quantity; #region Cập nhật lại quantity Entity new_salesorderdetail = new Entity(salesorderdetail.LogicalName, salesorderdetail.Id); new_salesorderdetail["bsd_suborderquantity"] = new_suborder_quantity; new_salesorderdetail["bsd_remainingquantity"] = new_remaining_quantity; myService.Update(new_salesorderdetail); #endregion } else { subService.DeleteSuborderProduct(suborder_product); } } } } #endregion TruCongNoFromSub(suborder); } } } #endregion }