<commit_before>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using TeaCommerce.Api.Common;
using TeaCommerce.Api.Models;
using TeaCommerce.Api.Services;
using TeaCommerce.Api.Web.PaymentProviders;
using TeaCommerce.PaymentProviders.Extensions;
using TeaCommerce.Api.Infrastructure.Logging;

namespace TeaCommerce.PaymentProviders {

  [PaymentProvider( "SagePay" )]
  public class SagePay : APaymentProvider {

    public override string DocumentationLink { get { return "http://anders.burla.dk/umbraco/tea-commerce/using-sage-pay-with-tea-commerce/"; } }

    public override bool SupportsCapturingOfPayment { get { return true; } }
    public override bool SupportsRefundOfPayment { get { return true; } }
    public override bool SupportsCancellationOfPayment { get { return true; } }

    public override IDictionary<string, string> DefaultSettings {
      get {
        Dictionary<string, string> defaultSettings = new Dictionary<string, string>();
        defaultSettings[ "Vendor" ] = string.Empty;
        defaultSettings[ "SuccessURL" ] = string.Empty;
        defaultSettings[ "FailureURL" ] = string.Empty;
        defaultSettings[ "TxType" ] = "AUTHENTICATE";
        defaultSettings[ "streetAddressPropertyAlias" ] = "streetAddress";
        defaultSettings[ "cityPropertyAlias" ] = "city";
        defaultSettings[ "zipCodePropertyAlias" ] = "zipCode";
        defaultSettings[ "Description" ] = "A description";
        defaultSettings[ "testMode" ] = "SIMULATOR";
        return defaultSettings;
      }
    }

    public override PaymentHtmlForm GenerateHtmlForm( Order order, string teaCommerceContinueUrl, string teaCommerceCancelUrl, string teaCommerceCallBackUrl, IDictionary<string, string> settings ) {
      order.MustNotBeNull( "order" );
      settings.MustNotBeNull( "settings" );
      settings.MustContainKey( "streetAddressPropertyAlias", "settings" );
      settings.MustContainKey( "cityPropertyAlias", "settings" );
      settings.MustContainKey( "zipCodePropertyAlias", "settings" );
      settings.MustContainKey( "Description", "settings" );

      PaymentHtmlForm htmlForm = new PaymentHtmlForm();

      string[] settingsToExclude = new[] { "streetAddressPropertyAlias", "cityPropertyAlias", "zipCodePropertyAlias", "phonePropertyAlias", "shipping_firstNamePropertyAlias", "shipping_lastNamePropertyAlias", "shipping_streetAddressPropertyAlias", "shipping_cityPropertyAlias", "shipping_zipCodePropertyAlias", "shipping_phonePropertyAlias", "testMode" };
      Dictionary<string, string> inputFields = settings.Where( i => !settingsToExclude.Contains( i.Key ) ).ToDictionary( i => i.Key, i => i.Value );

      inputFields[ "VPSProtocol" ] = "2.23";

      #region Address properties

      string streetAddress = order.Properties[ settings[ "streetAddressPropertyAlias" ] ];
      string city = order.Properties[ settings[ "cityPropertyAlias" ] ];
      string zipCode = order.Properties[ settings[ "zipCodePropertyAlias" ] ];

      streetAddress.MustNotBeNullOrEmpty( "streetAddress" );
      streetAddress.MustNotBeNullOrEmpty( "city" );
      streetAddress.MustNotBeNullOrEmpty( "zipCode" );

      string shippingFirstName = settings.ContainsKey( "shipping_firstNamePropertyAlias" ) ? order.Properties[ settings[ "shipping_firstNamePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingFirstName ) ) {
        shippingFirstName = order.PaymentInformation.FirstName;
      }

      string shippingLastName = settings.ContainsKey( "shipping_lastNamePropertyAlias" ) ? order.Properties[ settings[ "shipping_lastNamePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingLastName ) ) {
        shippingLastName = order.PaymentInformation.LastName;
      }

      string shippingStreetAddress = settings.ContainsKey( "shipping_streetAddressPropertyAlias" ) ? order.Properties[ settings[ "shipping_streetAddressPropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingStreetAddress ) ) {
        shippingStreetAddress = streetAddress;
      }

      string shippingCity = settings.ContainsKey( "shipping_cityPropertyAlias" ) ? order.Properties[ settings[ "shipping_cityPropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingCity ) ) {
        shippingCity = city;
      }

      string shippingZipCode = settings.ContainsKey( "shipping_zipCodePropertyAlias" ) ? order.Properties[ settings[ "shipping_zipCodePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingZipCode ) ) {
        shippingZipCode = zipCode;
      }

      #endregion

      inputFields[ "VendorTxCode" ] = order.CartNumber;
      inputFields[ "Amount" ] = order.TotalPrice.WithVat.ToString( "0.00", CultureInfo.InvariantCulture );

      //Check that the Iso code exists
      Currency currency = CurrencyService.Instance.Get( order.StoreId, order.CurrencyId );
      if ( !Iso4217CurrencyCodes.ContainsKey( currency.IsoCode ) ) {
        throw new Exception( "You must specify an ISO 4217 currency code for the " + currency.Name + " currency" );
      }
      inputFields[ "Currency" ] = currency.IsoCode;
      inputFields[ "Description" ] = inputFields[ "Description" ].Truncate( 100 );
      inputFields[ "SuccessURL" ] = teaCommerceContinueUrl;
      inputFields[ "FailureURL" ] = teaCommerceCancelUrl;
      inputFields[ "NotificationURL" ] = teaCommerceCallBackUrl;
      inputFields[ "BillingSurname" ] = order.PaymentInformation.LastName.Truncate( 20 );
      inputFields[ "BillingFirstnames" ] = order.PaymentInformation.FirstName.Truncate( 20 );
      inputFields[ "BillingAddress1" ] = streetAddress.Truncate( 100 );
      inputFields[ "BillingCity" ] = city.Truncate( 40 );
      inputFields[ "BillingPostCode" ] = zipCode.Truncate( 10 );

      Country country = CountryService.Instance.Get( order.StoreId, order.PaymentInformation.CountryId );
      inputFields[ "BillingCountry" ] = country.RegionCode;
      if ( country.RegionCode.ToUpperInvariant() == "US" && order.PaymentInformation.CountryRegionId != null ) {
        CountryRegion countryRegion = CountryRegionService.Instance.Get( order.StoreId, order.PaymentInformation.CountryRegionId.Value );
        inputFields[ "BillingState" ] = countryRegion.RegionCode.Truncate( 2 );
      }
      if ( settings.ContainsKey( "phonePropertyAlias" ) ) {
        inputFields[ "BillingPhone" ] = order.Properties[ settings[ "phonePropertyAlias" ] ].Truncate( 20 );
      }

      inputFields[ "DeliverySurname" ] = shippingLastName.Truncate( 20 );
      inputFields[ "DeliveryFirstnames" ] = shippingFirstName.Truncate( 20 );
      inputFields[ "DeliveryAddress1" ] = shippingStreetAddress.Truncate( 100 );
      inputFields[ "DeliveryCity" ] = shippingCity.Truncate( 40 );
      inputFields[ "DeliveryPostCode" ] = shippingZipCode.Truncate( 10 );
      if ( order.ShipmentInformation.CountryId != null ) {
        country = CountryService.Instance.Get( order.StoreId, order.ShipmentInformation.CountryId.Value );
        inputFields[ "DeliveryCountry" ] = country.RegionCode;
        if ( country.RegionCode.ToUpperInvariant() == "US" && order.ShipmentInformation.CountryRegionId != null ) {
          CountryRegion countryRegion = CountryRegionService.Instance.Get( order.StoreId, order.ShipmentInformation.CountryRegionId.Value );
          inputFields[ "DeliveryState" ] = countryRegion.RegionCode.Truncate( 2 );
        }
      }
      if ( settings.ContainsKey( "shipping_phonePropertyAlias" ) ) {
        inputFields[ "DeliveryPhone" ] = order.Properties[ settings[ "shipping_phonePropertyAlias" ] ].Truncate( 20 );
      }

      inputFields[ "Apply3DSecure" ] = "2";<commit_msg>Corrected SagePay to always send DeliveryCountry<commit_after>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using TeaCommerce.Api.Common;
using TeaCommerce.Api.Models;
using TeaCommerce.Api.Services;
using TeaCommerce.Api.Web.PaymentProviders;
using TeaCommerce.PaymentProviders.Extensions;
using TeaCommerce.Api.Infrastructure.Logging;

namespace TeaCommerce.PaymentProviders {

  [PaymentProvider( "SagePay" )]
  public class SagePay : APaymentProvider {

    public override string DocumentationLink { get { return "http://anders.burla.dk/umbraco/tea-commerce/using-sage-pay-with-tea-commerce/"; } }

    public override bool SupportsCapturingOfPayment { get { return true; } }
    public override bool SupportsRefundOfPayment { get { return true; } }
    public override bool SupportsCancellationOfPayment { get { return true; } }

    public override IDictionary<string, string> DefaultSettings {
      get {
        Dictionary<string, string> defaultSettings = new Dictionary<string, string>();
        defaultSettings[ "Vendor" ] = string.Empty;
        defaultSettings[ "SuccessURL" ] = string.Empty;
        defaultSettings[ "FailureURL" ] = string.Empty;
        defaultSettings[ "TxType" ] = "AUTHENTICATE";
        defaultSettings[ "streetAddressPropertyAlias" ] = "streetAddress";
        defaultSettings[ "cityPropertyAlias" ] = "city";
        defaultSettings[ "zipCodePropertyAlias" ] = "zipCode";
        defaultSettings[ "Description" ] = "A description";
        defaultSettings[ "testMode" ] = "SIMULATOR";
        return defaultSettings;
      }
    }

    public override PaymentHtmlForm GenerateHtmlForm( Order order, string teaCommerceContinueUrl, string teaCommerceCancelUrl, string teaCommerceCallBackUrl, IDictionary<string, string> settings ) {
      order.MustNotBeNull( "order" );
      settings.MustNotBeNull( "settings" );
      settings.MustContainKey( "streetAddressPropertyAlias", "settings" );
      settings.MustContainKey( "cityPropertyAlias", "settings" );
      settings.MustContainKey( "zipCodePropertyAlias", "settings" );
      settings.MustContainKey( "Description", "settings" );

      PaymentHtmlForm htmlForm = new PaymentHtmlForm();

      string[] settingsToExclude = new[] { "streetAddressPropertyAlias", "cityPropertyAlias", "zipCodePropertyAlias", "phonePropertyAlias", "shipping_firstNamePropertyAlias", "shipping_lastNamePropertyAlias", "shipping_streetAddressPropertyAlias", "shipping_cityPropertyAlias", "shipping_zipCodePropertyAlias", "shipping_phonePropertyAlias", "testMode" };
      Dictionary<string, string> inputFields = settings.Where( i => !settingsToExclude.Contains( i.Key ) ).ToDictionary( i => i.Key, i => i.Value );

      inputFields[ "VPSProtocol" ] = "2.23";

      #region Address properties

      string streetAddress = order.Properties[ settings[ "streetAddressPropertyAlias" ] ];
      string city = order.Properties[ settings[ "cityPropertyAlias" ] ];
      string zipCode = order.Properties[ settings[ "zipCodePropertyAlias" ] ];

      streetAddress.MustNotBeNullOrEmpty( "streetAddress" );
      city.MustNotBeNullOrEmpty( "city" );
      zipCode.MustNotBeNullOrEmpty( "zipCode" );

      string shippingFirstName = settings.ContainsKey( "shipping_firstNamePropertyAlias" ) ? order.Properties[ settings[ "shipping_firstNamePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingFirstName ) ) {
        shippingFirstName = order.PaymentInformation.FirstName;
      }

      string shippingLastName = settings.ContainsKey( "shipping_lastNamePropertyAlias" ) ? order.Properties[ settings[ "shipping_lastNamePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingLastName ) ) {
        shippingLastName = order.PaymentInformation.LastName;
      }

      string shippingStreetAddress = settings.ContainsKey( "shipping_streetAddressPropertyAlias" ) ? order.Properties[ settings[ "shipping_streetAddressPropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingStreetAddress ) ) {
        shippingStreetAddress = streetAddress;
      }

      string shippingCity = settings.ContainsKey( "shipping_cityPropertyAlias" ) ? order.Properties[ settings[ "shipping_cityPropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingCity ) ) {
        shippingCity = city;
      }

      string shippingZipCode = settings.ContainsKey( "shipping_zipCodePropertyAlias" ) ? order.Properties[ settings[ "shipping_zipCodePropertyAlias" ] ] : "";
      if ( string.IsNullOrEmpty( shippingZipCode ) ) {
        shippingZipCode = zipCode;
      }

      #endregion

      inputFields[ "VendorTxCode" ] = order.CartNumber;
      inputFields[ "Amount" ] = order.TotalPrice.WithVat.ToString( "0.00", CultureInfo.InvariantCulture );

      //Check that the Iso code exists
      Currency currency = CurrencyService.Instance.Get( order.StoreId, order.CurrencyId );
      if ( !Iso4217CurrencyCodes.ContainsKey( currency.IsoCode ) ) {
        throw new Exception( "You must specify an ISO 4217 currency code for the " + currency.Name + " currency" );
      }
      inputFields[ "Currency" ] = currency.IsoCode;
      inputFields[ "Description" ] = inputFields[ "Description" ].Truncate( 100 );
      inputFields[ "SuccessURL" ] = teaCommerceContinueUrl;
      inputFields[ "FailureURL" ] = teaCommerceCancelUrl;
      inputFields[ "NotificationURL" ] = teaCommerceCallBackUrl;
      inputFields[ "BillingSurname" ] = order.PaymentInformation.LastName.Truncate( 20 );
      inputFields[ "BillingFirstnames" ] = order.PaymentInformation.FirstName.Truncate( 20 );
      inputFields[ "BillingAddress1" ] = streetAddress.Truncate( 100 );
      inputFields[ "BillingCity" ] = city.Truncate( 40 );
      inputFields[ "BillingPostCode" ] = zipCode.Truncate( 10 );

      Country country = CountryService.Instance.Get( order.StoreId, order.PaymentInformation.CountryId );
      inputFields[ "BillingCountry" ] = country.RegionCode;
      if ( country.RegionCode.ToUpperInvariant() == "US" && order.PaymentInformation.CountryRegionId != null ) {
        CountryRegion countryRegion = CountryRegionService.Instance.Get( order.StoreId, order.PaymentInformation.CountryRegionId.Value );
        inputFields[ "BillingState" ] = countryRegion.RegionCode.Truncate( 2 );
      }
      if ( settings.ContainsKey( "phonePropertyAlias" ) ) {
        inputFields[ "BillingPhone" ] = order.Properties[ settings[ "phonePropertyAlias" ] ].Truncate( 20 );
      }

      inputFields[ "DeliverySurname" ] = shippingLastName.Truncate( 20 );
      inputFields[ "DeliveryFirstnames" ] = shippingFirstName.Truncate( 20 );
      inputFields[ "DeliveryAddress1" ] = shippingStreetAddress.Truncate( 100 );
      inputFields[ "DeliveryCity" ] = shippingCity.Truncate( 40 );
      inputFields[ "DeliveryPostCode" ] = shippingZipCode.Truncate( 10 );

      country = CountryService.Instance.Get( order.StoreId, order.ShipmentInformation.CountryId ?? order.PaymentInformation.CountryId );
      inputFields[ "DeliveryCountry" ] = country.RegionCode;

      long? shippingCountryRegionId = order.ShipmentInformation.CountryId != null ? order.ShipmentInformation.CountryRegionId : order.PaymentInformation.CountryRegionId;
      if ( country.RegionCode.ToUpperInvariant() == "US" && shippingCountryRegionId != null ) {
        CountryRegion countryRegion = CountryRegionService.Instance.Get( order.StoreId, shippingCountryRegionId.Value );
        inputFields[ "DeliveryState" ] = countryRegion.RegionCode.Truncate( 2 );
      }
      if ( settings.ContainsKey( "shipping_phonePropertyAlias" ) ) {
        inputFields[ "DeliveryPhone" ] = order.Properties[ settings[ "shipping_phonePropertyAlias" ] ].Truncate( 20 );
      }

      inputFields[ "Apply3DSecure" ] = "2";
{'fraction_non_alphanumeric': 0.11073242878271494, 'fraction_numerical': 0.006301845540479712, 'mean_word_length': 4.185728576192064, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5775413', 'n_tokens_mistral': 4439, 'n_tokens_neox': 4289, 'n_words': 842}