/// <summary> /// Update entity in invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='invoiceid'> /// key: invoiceid /// </param> /// <param name='body'> /// New property values /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public static async Task UpdateAsync(this IInvoices operations, string invoiceid, MicrosoftDynamicsCRMinvoice body, CancellationToken cancellationToken = default(CancellationToken)) { (await operations.UpdateWithHttpMessagesAsync(invoiceid, body, null, cancellationToken).ConfigureAwait(false)).Dispose(); }
/// <summary> /// Add new entity to invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='body'> /// New entity /// </param> /// <param name='prefer'> /// Required in order for the service to return a JSON representation of the /// object. /// </param> public static MicrosoftDynamicsCRMinvoice Create(this IInvoices operations, MicrosoftDynamicsCRMinvoice body, string prefer = "return=representation") { return(operations.CreateAsync(body, prefer).GetAwaiter().GetResult()); }
/// <summary> /// Add new entity to invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='body'> /// New entity /// </param> /// <param name='prefer'> /// Required in order for the service to return a JSON representation of the /// object. /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public static async Task <MicrosoftDynamicsCRMinvoice> CreateAsync(this IInvoices operations, MicrosoftDynamicsCRMinvoice body, string prefer = "return=representation", CancellationToken cancellationToken = default(CancellationToken)) { using (var _result = await operations.CreateWithHttpMessagesAsync(body, prefer, null, cancellationToken).ConfigureAwait(false)) { return(_result.Body); } }
/// <summary> /// Update entity in invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='invoiceid'> /// key: invoiceid /// </param> /// <param name='body'> /// New property values /// </param> public static void Update(this IInvoices operations, string invoiceid, MicrosoftDynamicsCRMinvoice body) { operations.UpdateAsync(invoiceid, body).GetAwaiter().GetResult(); }
/// <summary> /// Update entity in invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='invoiceid'> /// key: invoiceid of invoice /// </param> /// <param name='body'> /// New property values /// </param> /// <param name='customHeaders'> /// Headers that will be added to request. /// </param> public static HttpOperationResponse UpdateWithHttpMessages(this IInvoices operations, string invoiceid, MicrosoftDynamicsCRMinvoice body, Dictionary <string, List <string> > customHeaders = null) { return(operations.UpdateWithHttpMessagesAsync(invoiceid, body, customHeaders, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult()); }
/// <summary> /// Update entity in invoices /// </summary> /// <param name='invoiceid'> /// key: invoiceid /// </param> /// <param name='body'> /// New property values /// </param> /// <param name='customHeaders'> /// Headers that will be added to request. /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> /// <exception cref="OdataerrorException"> /// Thrown when the operation returned an invalid status code /// </exception> /// <exception cref="ValidationException"> /// Thrown when a required parameter is null /// </exception> /// <exception cref="System.ArgumentNullException"> /// Thrown when a required parameter is null /// </exception> /// <return> /// A response object containing the response body and response headers. /// </return> public async Task <HttpOperationResponse> UpdateWithHttpMessagesAsync(string invoiceid, MicrosoftDynamicsCRMinvoice body, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) { if (invoiceid == null) { throw new ValidationException(ValidationRules.CannotBeNull, "invoiceid"); } if (body == null) { throw new ValidationException(ValidationRules.CannotBeNull, "body"); } // Tracing bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("invoiceid", invoiceid); tracingParameters.Add("body", body); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(_invocationId, this, "Update", tracingParameters); } // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "invoices({invoiceid})").ToString(); _url = _url.Replace("{invoiceid}", System.Uri.EscapeDataString(invoiceid)); // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("PATCH"); _httpRequest.RequestUri = new System.Uri(_url); // Set Headers if (customHeaders != null) { foreach (var _header in customHeaders) { if (_httpRequest.Headers.Contains(_header.Key)) { _httpRequest.Headers.Remove(_header.Key); } _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); } } // Serialize Request string _requestContent = null; if (body != null) { _requestContent = Microsoft.Rest.Serialization.SafeJsonConvert.SerializeObject(body, Client.SerializationSettings); _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); _httpRequest.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); } // Set Credentials if (Client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } // Send Request if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } cancellationToken.ThrowIfCancellationRequested(); _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } HttpStatusCode _statusCode = _httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); string _responseContent = null; if ((int)_statusCode != 204) { var ex = new OdataerrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); try { _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); Odataerror _errorBody = Microsoft.Rest.Serialization.SafeJsonConvert.DeserializeObject <Odataerror>(_responseContent, Client.DeserializationSettings); if (_errorBody != null) { ex.Body = _errorBody; } } catch (JsonException) { // Ignore the exception } ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); if (_shouldTrace) { ServiceClientTracing.Error(_invocationId, ex); } _httpRequest.Dispose(); if (_httpResponse != null) { _httpResponse.Dispose(); } throw ex; } // Create Result var _result = new HttpOperationResponse(); _result.Request = _httpRequest; _result.Response = _httpResponse; if (_shouldTrace) { ServiceClientTracing.Exit(_invocationId, _result); } return(_result); }
public async Task <IActionResult> VerifyWorkerPaymentStatus(string workerId) { MicrosoftDynamicsCRMadoxioWorker worker = await GetDynamicsWorker(workerId, true); if (worker == null) { return(NotFound()); } // load the invoice for this application string invoiceId = worker._adoxioInvoiceValue; _logger.LogDebug("Found invoice for application = " + invoiceId); MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); var ordernum = invoice.AdoxioTransactionid; var orderamt = invoice.Totalamount; var response = await _bcep.ProcessPaymentResponse(ordernum, workerId); response["invoice"] = invoice.Invoicenumber; foreach (var key in response.Keys) { _logger.LogDebug(">>>>>" + key + ":" + response[key]); } /* * - if the invoice status is not "New", skip * - we will update the Invoice status to "Complete" (if paid) or "Cancelled" (if payment was rejected) * - if payment is successful, we will also set the Application "Payment Received" to "Y" and "Method" to "Credit Card" */ if (invoice.Statecode == (int?)Adoxio_invoicestates.New || invoice.Statecode == null) { _logger.LogDebug("Processing invoice with status New"); // if payment was successful: var pay_status = response["trnApproved"]; if (pay_status == "1") { _logger.LogDebug("Transaction approved"); MicrosoftDynamicsCRMinvoice invoice2 = new MicrosoftDynamicsCRMinvoice() { // set invoice status to Complete Statecode = (int?)Adoxio_invoicestates.Paid, Statuscode = (int?)Adoxio_invoicestatuses.Paid, AdoxioReturnedtransactionid = response["trnId"] }; try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, invoice2); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating invoice"); // fail throw (httpOperationException); } MicrosoftDynamicsCRMadoxioWorker patchWorker = new MicrosoftDynamicsCRMadoxioWorker() { // set the Application payment status AdoxioPaymentreceived = 1, AdoxioPaymentreceiveddate = DateTime.UtcNow }; try { _dynamicsClient.Workers.Update(workerId, patchWorker); } catch (HttpOperationException httpOperationException) { _logger.LogError("Error updating worker"); _logger.LogError("Request:"); _logger.LogError(httpOperationException.Request.Content); _logger.LogError("Response:"); _logger.LogError(httpOperationException.Response.Content); // fail throw (httpOperationException); } } // if payment failed: else { _logger.LogDebug("Transaction NOT approved"); // set invoice status to Cancelled MicrosoftDynamicsCRMinvoice patchInvoice = new MicrosoftDynamicsCRMinvoice() { Statecode = (int?)Adoxio_invoicestates.Cancelled, Statuscode = (int?)Adoxio_invoicestatuses.Cancelled }; try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, patchInvoice); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating invoice"); // fail throw (httpOperationException); } // set the Application invoice status back to No MicrosoftDynamicsCRMadoxioWorker patchWorker = new MicrosoftDynamicsCRMadoxioWorker() { // set the Application payment status AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.No }; try { _dynamicsClient.Workers.Update(workerId, patchWorker); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating worker"); // fail throw (httpOperationException); } } } else { // that can happen if we are re-validating a completed invoice (paid or cancelled) _logger.LogDebug("Invoice status is not New, skipping updates ..."); } return(new JsonResult(response)); }
/// <summary> /// Add new entity to invoices /// </summary> /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='body'> /// New entity /// </param> /// <param name='prefer'> /// Required in order for the service to return a JSON representation of the /// object. /// </param> /// <param name='customHeaders'> /// Headers that will be added to request. /// </param> public static HttpOperationResponse <MicrosoftDynamicsCRMinvoice> CreateWithHttpMessages(this IInvoices operations, MicrosoftDynamicsCRMinvoice body, string prefer = "return=representation", Dictionary <string, List <string> > customHeaders = null) { return(operations.CreateWithHttpMessagesAsync(body, prefer, customHeaders, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult()); }
public async Task <IActionResult> VerifyLicenceFeePaymentStatus(string id) { MicrosoftDynamicsCRMadoxioApplication adoxioApplication = await GetDynamicsApplication(id); if (adoxioApplication == null) { return(NotFound()); } // load the invoice for this application string invoiceId = adoxioApplication._adoxioLicencefeeinvoiceValue; _logger.LogDebug("Found invoice for application = " + invoiceId); MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); var ordernum = invoice.AdoxioTransactionid; var orderamt = invoice.Totalamount; var response = await _bcep.ProcessPaymentResponse(ordernum, id); response["invoice"] = invoice.Invoicenumber; foreach (var key in response.Keys) { _logger.LogDebug(">>>>>" + key + ":" + response[key]); } /* * - if the invoice status is not "New", skip * - we will update the Invoice status to "Complete" (if paid) or "Cancelled" (if payment was rejected) * - if payment is successful, we will also set the Application "Payment Received" to "Y" and "Method" to "Credit Card" */ if (invoice.Statecode == (int?)Adoxio_invoicestates.New || invoice.Statecode == null) { _logger.LogDebug("Processing invoice with status New"); // if payment was successful: var pay_status = response["trnApproved"]; if (pay_status == "1") { _logger.LogDebug("Transaction approved"); MicrosoftDynamicsCRMinvoice patchInvoice = new MicrosoftDynamicsCRMinvoice() { // set invoice status to Complete Statecode = (int?)Adoxio_invoicestates.Paid, Statuscode = (int?)Adoxio_invoicestatuses.Paid, AdoxioReturnedtransactionid = response["trnId"] }; try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, patchInvoice); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating invoice"); // fail throw (httpOperationException); } // set the Application payment status MicrosoftDynamicsCRMadoxioApplication patchApplication = new MicrosoftDynamicsCRMadoxioApplication() { AdoxioLicencefeeinvoicepaid = true }; try { _dynamicsClient.Applications.Update(id, patchApplication); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating application"); // fail throw (httpOperationException); } // trigger geocoding if (!string.IsNullOrEmpty(_configuration["FEATURE_MAPS"])) { await _geocoderClient.GeocodeEstablishment(adoxioApplication._adoxioLicenceestablishmentValue, _logger); } } // if payment failed: else { _logger.LogDebug("Transaction NOT approved"); MicrosoftDynamicsCRMinvoice patchInvoice = new MicrosoftDynamicsCRMinvoice() { // set invoice status to Cancelled Statecode = (int?)Adoxio_invoicestates.Cancelled, Statuscode = (int?)Adoxio_invoicestatuses.Cancelled }; try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, patchInvoice); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating invoice"); // fail throw (httpOperationException); } // set the Application invoice status back to No MicrosoftDynamicsCRMadoxioApplication patchApplication = new MicrosoftDynamicsCRMadoxioApplication() { AdoxioLicencefeeinvoicetrigger = (int?)ViewModels.GeneralYesNo.No }; try { _dynamicsClient.Applications.Update(id, patchApplication); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating application"); // fail throw (httpOperationException); } } } else { // that can happen if we are re-validating a completed invoice (paid or cancelled) _logger.LogDebug("Invoice status is not New, skipping updates ..."); } return(new JsonResult(response)); }
public async Task <IActionResult> GetWorkerPaymentUrl(string workerId) { _logger.LogDebug($"Called GetWorkerPaymentUrl({workerId})"); // get the application and confirm access (call parse to ensure we are getting a valid id) Guid workerGuid = Guid.Parse(workerId); MicrosoftDynamicsCRMadoxioWorker worker = await GetDynamicsWorker(workerId, true); if (worker == null) { return(NotFound()); } if (worker.AdoxioInvoice?.Statuscode == (int?)Adoxio_invoicestatuses.Paid) { return(NotFound("Payment already made")); } // set the application invoice trigger to create an invoice MicrosoftDynamicsCRMadoxioWorker patchWorker = new MicrosoftDynamicsCRMadoxioWorker() { // this is the money - setting this flag to "Y" triggers a dynamics workflow that creates an invoice AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.Yes }; try { _dynamicsClient.Workers.Update(workerId, patchWorker); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating worker"); // fail throw (httpOperationException); } // we set the getInvoice parameter to false here as there is a chance the Invoice is not created yet - so we may not be able to expand. patchWorker = await GetDynamicsWorker(workerId, false); // now load the invoice for this application to get the pricing string invoiceId = patchWorker._adoxioInvoiceValue; int retries = 0; while (retries < 10 && (invoiceId == null || invoiceId.Length == 0)) { // should happen immediately, but ... // pause and try again - in case Dynamics is slow ... retries++; _logger.LogDebug("No invoice found, retry = " + retries); System.Threading.Thread.Sleep(1000); patchWorker = await GetDynamicsWorker(workerId, false); invoiceId = patchWorker._adoxioInvoiceValue; } _logger.LogDebug("Created invoice for worker = " + invoiceId); /* * When the applicant submits their Application, we will set the application "Application Invoice Trigger" to "Y" - this will trigger a workflow that will create the Invoice * - we will then re-query the Application to get the Invoice number, * - and then query the Invoice to get the amount * - the Invoice will also contain a Transaction Id (starting at 0500000000) * - the Invoice status will be New * Notes: * - If there is already an invoice with Status New, don't need to create a new Invoice * - If there is already an invoice with Status Complete, it is an error (can't pay twice) * - We will deal with the history later (i.e. there can be multiple "Cancelled" Invoices - we need to keep them for reconciliation but we don't need them for MVP */ MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); // dynamics creates a unique transaction id per invoice, used as the "order number" for payment var ordernum = invoice.AdoxioTransactionid; // dynamics determines the amount based on the licence type of the application var orderamt = invoice.Totalamount; Dictionary <string, string> redirectUrl; redirectUrl = new Dictionary <string, string>(); var redirectPath = _configuration["BASE_URI"] + _configuration["BASE_PATH"] + "/worker-qualification/payment-confirmation"; redirectUrl["url"] = _bcep.GeneratePaymentRedirectUrl(ordernum, workerId, String.Format("{0:0.00}", orderamt), redirectPath); _logger.LogDebug(">>>>>" + redirectUrl["url"]); return(new JsonResult(redirectUrl)); }
public async Task <IActionResult> GetLicencePaymentUrl(string id) { _logger.LogDebug("Called GetLicencePaymentUrl(" + id + ")"); // get the application and confirm access (call parse to ensure we are getting a valid id) Guid applicationId = Guid.Parse(id); MicrosoftDynamicsCRMadoxioApplication application = await GetDynamicsApplication(id); if (application == null) { return(NotFound()); } if (application.AdoxioLicenceFeeInvoice?.Statuscode == (int?)Adoxio_invoicestatuses.Paid) { if (application.AdoxioLicencefeeinvoicepaid == false) { try { MicrosoftDynamicsCRMadoxioApplication fixApplication = new MicrosoftDynamicsCRMadoxioApplication() { AdoxioLicencefeeinvoicepaid = true }; _dynamicsClient.Applications.Update(id, fixApplication); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating application"); // fail throw (httpOperationException); } } return(NotFound("Payment already made")); } if (!string.IsNullOrEmpty(application._adoxioLicencefeeinvoiceValue)) { MicrosoftDynamicsCRMinvoice invoice2 = await _dynamicsClient.GetInvoiceById(Guid.Parse(application._adoxioLicencefeeinvoiceValue)); if (invoice2 != null && invoice2.Statecode == (int)Adoxio_invoicestates.Cancelled) { // set the application invoice trigger to create an invoice MicrosoftDynamicsCRMadoxioApplication adoxioApplication2 = new MicrosoftDynamicsCRMadoxioApplication() { // this is the money - setting this flag to "Y" triggers a dynamics workflow that creates an invoice AdoxioLicencefeeinvoicetrigger = (int?)ViewModels.GeneralYesNo.Yes }; try { _dynamicsClient.Applications.Update(id, adoxioApplication2); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating application"); // fail throw (httpOperationException); } application = await GetDynamicsApplication(id); } } string invoiceId = application._adoxioLicencefeeinvoiceValue; int retries = 0; while (retries < 10 && string.IsNullOrEmpty(invoiceId)) { // should happen immediately, but ... // pause and try again - in case Dynamics is slow ... retries++; _logger.LogDebug("No invoice found, retry = " + retries); System.Threading.Thread.Sleep(1000); application = await GetDynamicsApplication(id); invoiceId = application._adoxioInvoiceValue; } _logger.LogDebug("Created invoice for application = " + invoiceId); /* * When the applicant submits their Application, we will set the application "Application Invoice Trigger" to "Y" - this will trigger a workflow that will create the Invoice * - we will then re-query the Application to get the Invoice number, * - and then query the Invoice to get the amount * - the Invoice will also contain a Transaction Id (starting at 0500000000) * - the Invoice status will be New * Notes: * - If there is already an invoice with Status New, don't need to create a new Invoice * - If there is already an invoice with Status Complete, it is an error (can't pay twice) * - We will deal with the history later (i.e. there can be multiple "Cancelled" Invoices - we need to keep them for reconciliation but we don't need them for MVP */ MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); // dynamics creates a unique transaction id per invoice, used as the "order number" for payment var ordernum = invoice.AdoxioTransactionid; // dynamics determines the amount based on the licence type of the application var orderamt = invoice.Totalamount; Dictionary <string, string> redirectUrl; redirectUrl = new Dictionary <string, string>(); var redirectPath = _configuration["BASE_URI"] + _configuration["BASE_PATH"] + "/licence-fee-payment-confirmation"; redirectUrl["url"] = _bcep.GeneratePaymentRedirectUrl(ordernum, id, String.Format("{0:0.00}", orderamt), redirectPath); _logger.LogDebug(">>>>>" + redirectUrl["url"]); return(new JsonResult(redirectUrl)); }
public async Task <IActionResult> GetPaymentUrl(string id) { _logger.LogError("Called GetPaymentUrl(" + id + ")"); // get the application and confirm access (call parse to ensure we are getting a valid id) Guid applicationId = Guid.Parse(id); MicrosoftDynamicsCRMadoxioApplication adoxioApplication = await GetDynamicsApplication(id); if (adoxioApplication == null) { return(NotFound()); } // set the application invoice trigger to create an invoice ViewModels.AdoxioApplication vm = await adoxioApplication.ToViewModel(_dynamicsClient); MicrosoftDynamicsCRMadoxioApplication adoxioApplication2 = new MicrosoftDynamicsCRMadoxioApplication(); adoxioApplication2.CopyValues(vm); // this is the money - setting this flag to "Y" triggers a dynamics workflow that creates an invoice adoxioApplication2.AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.Yes; _dynamicsClient.Applications.Update(id, adoxioApplication2); adoxioApplication2 = await GetDynamicsApplication(id); // now load the invoice for this application to get the pricing string invoiceId = adoxioApplication2._adoxioInvoiceValue; int retries = 0; while (retries < 10 && (invoiceId == null || invoiceId.Length == 0)) { // should happen immediately, but ... // pause and try again - in case Dynamics is slow ... retries++; _logger.LogError("No invoice found, retry = " + retries); System.Threading.Thread.Sleep(1000); invoiceId = adoxioApplication2._adoxioInvoiceValue; } _logger.LogError("Created invoice for application = " + invoiceId); /* * When the applicant submits their Application, we will set the application "Application Invoice Trigger" to "Y" - this will trigger a workflow that will create the Invoice * - we will then re-query the Application to get the Invoice number, * - and then query the Invoice to get the amount * - the Invoice will also contain a Transaction Id (starting at 0500000000) * - the Invoice status will be New * Notes: * - If there is already an invoice with Status New, don't need to create a new Invoice * - If there is already an invoice with Status Complete, it is an error (can't pay twice) * - We will deal with the history later (i.e. there can be multiple "Cancelled" Invoices - we need to keep them for reconciliation but we don't need them for MVP */ MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); // dynamics creates a unique transaction id per invoice, used as the "order number" for payment var ordernum = invoice.AdoxioTransactionid; // dynamics determines the amount based on the licence type of the application var orderamt = invoice.Totalamount; Dictionary <string, string> redirectUrl; redirectUrl = new Dictionary <string, string>(); redirectUrl["url"] = _bcep.GeneratePaymentRedirectUrl(ordernum, id, String.Format("{0:0.00}", orderamt)); _logger.LogError(">>>>>" + redirectUrl["url"]); return(Json(redirectUrl)); }
public async Task <IActionResult> VerifyWorkerPaymentStatus(string workerId) { MicrosoftDynamicsCRMadoxioWorker worker = await GetDynamicsWorker(workerId); if (worker == null) { return(NotFound()); } // load the invoice for this application string invoiceId = worker._adoxioInvoiceValue; _logger.LogError("Found invoice for application = " + invoiceId); MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(Guid.Parse(invoiceId)); var ordernum = invoice.AdoxioTransactionid; var orderamt = invoice.Totalamount; var response = await _bcep.ProcessPaymentResponse(ordernum, workerId); response["invoice"] = invoice.Invoicenumber; foreach (var key in response.Keys) { _logger.LogError(">>>>>" + key + ":" + response[key]); } /* * - if the invoice status is not "New", skip * - we will update the Invoice status to "Complete" (if paid) or "Cancelled" (if payment was rejected) * - if payment is successful, we will also set the Application "Payment Received" to "Y" and "Method" to "Credit Card" */ if (invoice.Statecode == (int?)Adoxio_invoicestates.New || invoice.Statecode == null) { _logger.LogError("Processing invoice with status New"); ViewModels.Invoice vmi = invoice.ToViewModel(); MicrosoftDynamicsCRMinvoice invoice2 = new MicrosoftDynamicsCRMinvoice(); invoice2.CopyValues(vmi); ViewModels.Worker workerVM = worker.ToViewModel(); var patchWorker = new MicrosoftDynamicsCRMadoxioWorker(); patchWorker.CopyValues(workerVM); // if payment was successful: var pay_status = response["trnApproved"]; if (pay_status == "1") { _logger.LogError("Transaction approved"); // set invoice status to Complete invoice2.Statecode = (int?)Adoxio_invoicestates.Paid; invoice2.Statuscode = (int?)Adoxio_invoicestatuses.Paid; invoice2.AdoxioReturnedtransactionid = response["trnId"]; _dynamicsClient.Invoices.Update(invoice2.Invoiceid, invoice2); // set the Application payment status patchWorker.AdoxioPaymentreceived = 1; patchWorker.AdoxioPaymentreceiveddate = DateTime.UtcNow; //patchWorker.AdoxioPaymentmethod = (int?)Adoxio_paymentmethods.CC; //patchWorker.AdoxioAppchecklistpaymentreceived = (int?)ViewModels.GeneralYesNo.Yes; _dynamicsClient.Workers.Update(workerId, patchWorker); patchWorker = await GetDynamicsWorker(workerId); } // if payment failed: else { _logger.LogError("Transaction NOT approved"); // set invoice status to Cancelled invoice2.Statecode = (int?)Adoxio_invoicestates.Cancelled; invoice2.Statuscode = (int?)Adoxio_invoicestatuses.Cancelled; _dynamicsClient.Invoices.Update(invoice2.Invoiceid, invoice2); // set the Application invoice status back to No patchWorker.AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.No; // don't clear the invoice, leave the previous "Cancelled" so we can report status //adoxioApplication2._adoxioInvoiceValue = null; //adoxioApplication2.AdoxioInvoice = null; _dynamicsClient.Workers.Update(workerId, patchWorker); patchWorker = await GetDynamicsWorker(workerId); } } else { // that can happen if we are re-validating a completed invoice (paid or cancelled) _logger.LogError("Invoice status is not New, skipping updates ..."); } return(Json(response)); }
public async Task <IActionResult> VerifyPaymentStatus(string id) { MicrosoftDynamicsCRMadoxioApplication adoxioApplication = await GetDynamicsApplication(id, false); if (adoxioApplication == null) { return(NotFound()); } // load the invoice for this application string invoiceId = adoxioApplication._adoxioInvoiceValue; Guid invoiceGuid = Guid.Parse(invoiceId); _logger.LogInformation("Found invoice for application = " + invoiceId); MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(invoiceGuid); var ordernum = invoice.AdoxioTransactionid; var orderamt = invoice.Totalamount; var response = await _bcep.ProcessPaymentResponse(ordernum, id); response["invoice"] = invoice.Invoicenumber; foreach (var key in response.Keys) { _logger.LogInformation(">>>>>" + key + ":" + response[key]); } /* * - if the invoice status is not "New", skip * - we will update the Invoice status to "Complete" (if paid) or "Cancelled" (if payment was rejected) * - if payment is successful, we will also set the Application "Payment Received" to "Y" and "Method" to "Credit Card" */ if (invoice.Statecode == (int?)Adoxio_invoicestates.New || invoice.Statecode == null) { _logger.LogInformation("Processing invoice with status New"); // if payment was successful: var pay_status = response["trnApproved"]; if (pay_status == "1") { _logger.LogError("Transaction approved"); MicrosoftDynamicsCRMinvoice invoice2 = new MicrosoftDynamicsCRMinvoice() { Statecode = (int?)Adoxio_invoicestates.Paid, Statuscode = (int?)Adoxio_invoicestatuses.Paid, AdoxioReturnedtransactionid = response["trnId"] }; // set invoice status to Complete try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, invoice2); } catch (OdataerrorException odee) { _logger.LogError("Error updating invoice"); _logger.LogError("Request:"); _logger.LogError(odee.Request.Content); _logger.LogError("Response:"); _logger.LogError(odee.Response.Content); // fail throw (odee); } MicrosoftDynamicsCRMadoxioApplication adoxioApplication2 = new MicrosoftDynamicsCRMadoxioApplication() { // set the Application payment status AdoxioPaymentrecieved = (bool?)true, AdoxioPaymentmethod = (int?)Adoxio_paymentmethods.CC, AdoxioAppchecklistpaymentreceived = (int?)ViewModels.GeneralYesNo.Yes }; try { _dynamicsClient.Applications.Update(id, adoxioApplication2); } catch (OdataerrorException odee) { _logger.LogError("Error updating application"); _logger.LogError("Request:"); _logger.LogError(odee.Request.Content); _logger.LogError("Response:"); _logger.LogError(odee.Response.Content); // fail throw (odee); } } // if payment failed: else { _logger.LogError("Transaction NOT approved"); // set invoice status to Cancelled MicrosoftDynamicsCRMinvoice invoice2 = new MicrosoftDynamicsCRMinvoice() { Statecode = (int?)Adoxio_invoicestates.Cancelled, Statuscode = (int?)Adoxio_invoicestatuses.Cancelled }; try { _dynamicsClient.Invoices.Update(invoice.Invoiceid, invoice2); } catch (OdataerrorException odee) { _logger.LogError("Error updating invoice"); _logger.LogError("Request:"); _logger.LogError(odee.Request.Content); _logger.LogError("Response:"); _logger.LogError(odee.Response.Content); // fail throw (odee); } // set the Application invoice status back to No MicrosoftDynamicsCRMadoxioApplication adoxioApplication2 = new MicrosoftDynamicsCRMadoxioApplication() { AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.No }; try { _dynamicsClient.Applications.Update(id, adoxioApplication2); } catch (OdataerrorException odee) { _logger.LogError("Error updating application"); _logger.LogError("Request:"); _logger.LogError(odee.Request.Content); _logger.LogError("Response:"); _logger.LogError(odee.Response.Content); // fail throw (odee); } } } else { // that can happen if we are re-validating a completed invoice (paid or cancelled) _logger.LogError("Invoice status is not New, skipping updates ..."); } return(Json(response)); }
public async Task <IActionResult> GetPaymentUrl(string id) { _logger.LogDebug("Called GetPaymentUrl(" + id + ")"); // get the application and confirm access (call parse to ensure we are getting a valid id) Guid applicationId = Guid.Parse(id); MicrosoftDynamicsCRMadoxioApplication application = await GetDynamicsApplication(id); if (application == null) { return(NotFound()); } if (application.AdoxioInvoice?.Statuscode == (int?)Adoxio_invoicestatuses.Paid) { return(NotFound("Payment already made")); } // set the application invoice trigger to create an invoice // no need to copy the whole record over as we are doing a Patch for a single field. MicrosoftDynamicsCRMadoxioApplication patchApplication = new MicrosoftDynamicsCRMadoxioApplication() { // this is the money - setting this flag to "Y" triggers a dynamics workflow that creates an invoice AdoxioInvoicetrigger = (int?)ViewModels.GeneralYesNo.Yes }; try { _dynamicsClient.Applications.Update(id, patchApplication); } catch (HttpOperationException httpOperationException) { _logger.LogError(httpOperationException, "Error updating application"); // fail throw (httpOperationException); } application = await GetDynamicsApplication(id); // now load the invoice for this application to get the pricing string invoiceId = application._adoxioInvoiceValue; int retries = 0; while (retries < 10 && (invoiceId == null || invoiceId.Length == 0)) { // should happen immediately, but ... // pause and try again - in case Dynamics is slow ... retries++; _logger.LogError($"No application {id} invoice found, retry = " + retries); System.Threading.Thread.Sleep(1000); application = await GetDynamicsApplication(id); invoiceId = application._adoxioInvoiceValue; } if (!string.IsNullOrEmpty(invoiceId)) { _logger.LogDebug("Created invoice for application = " + invoiceId); /* * When the applicant submits their Application, we will set the application "Application Invoice Trigger" to "Y" - this will trigger a workflow that will create the Invoice * - we will then re-query the Application to get the Invoice number, * - and then query the Invoice to get the amount * - the Invoice will also contain a Transaction Id (starting at 0500000000) * - the Invoice status will be New * Notes: * - If there is already an invoice with Status New, don't need to create a new Invoice * - If there is already an invoice with Status Complete, it is an error (can't pay twice) * - We will deal with the history later (i.e. there can be multiple "Cancelled" Invoices - we need to keep them for reconciliation but we don't need them for MVP */ MicrosoftDynamicsCRMinvoice invoice = await _dynamicsClient.GetInvoiceById(invoiceId); // dynamics creates a unique transaction id per invoice, used as the "order number" for payment var ordernum = invoice.AdoxioTransactionid; // dynamics determines the amount based on the licence type of the application var orderamt = invoice.Totalamount; Dictionary <string, string> redirectUrl; redirectUrl = new Dictionary <string, string>(); bool isAlternateAccount = application.IsLiquor(); // set to true for Liquor. redirectUrl["url"] = _bcep.GeneratePaymentRedirectUrl(ordernum, id, String.Format("{0:0.00}", orderamt), isAlternateAccount); _logger.LogDebug(">>>>>" + redirectUrl["url"]); return(new JsonResult(redirectUrl)); } else { _logger.LogError("GetPaymentUrl failed - Unable to get invoice for application {id}"); return(NotFound()); } }