<commit_before>﻿using Braintree;
using System;
using LcEnum;

public partial class LcPayment
{
    public class Membership
    {
        #region Gateway
        private BraintreeGateway _gateway;

        private BraintreeGateway Gateway
        {
			get {
				if (_gateway == null) {
					_gateway = NewBraintreeGateway();
				}
                return _gateway;
			}
        }
        #endregion

        #region Class
        public Membership() { }
        #endregion

        #region IDs
        /// <summary>
        /// Get the payment gateway ID for a customer based in our userID
        /// with a specific format to use for 'fee payments'; this
        /// allow us to easy distinguish transactions of the user made
        /// to pay membership/ownership fees and payments to other professionals
        /// as a marketplace client (as of LcPayemnt.GetCustomerId)
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public static string GetFeePaymentUserId(int userID)
        {
            return ASP.LcHelpers.Channel + "_fee_" + userID.ToString();
        }
        #endregion

        #region Subscription

        /// <summary>
        /// Returns the correct descriptor name for the given plan,
        /// following gateway naming restrictions.
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        public string GetSubscriptionPlanDescriptor(SubscriptionPlan plan)
        {
            // IMPORTANT: Braintree restricts the naming possibilities
            // as described at https://developers.braintreepayments.com/reference/request/transaction/sale/dotnet#descriptor.name
            // Copied: Company name/DBA section must be either 3, 7 or 12 characters
            // and the product descriptor can be up to 18, 14, or 9 characters respectively (with an * in between
            // for a total descriptor name of 22 characters)
            // NOTE: We choose 12 chars for 'Loconomics  ' (double white space in the end
            // to match twelve) plus short plan name ('ProAnnual' fits exactly, 9)
            switch (plan)
            {
                case SubscriptionPlan.Free:
                    throw new ArgumentException("A free plan don't need a paid subscription");
                case SubscriptionPlan.OwnerProAnnual:
                    return "Loconomics  *ProAnnual";
                case SubscriptionPlan.OwnerPro:
                    return "Loconomics  *Pro";
                case SubscriptionPlan.OwnerGrowth:
                    return "Loconomics  *Growth";
                default:
                    throw new ArgumentException("Plan value unsupported");
            }
        }

        public Subscription CreateSubscription(SubscriptionPlan plan, string paymentMethodToken, DateTimeOffset trialEndDate)
        {
            var descriptor = new DescriptorRequest
            {
                Name = GetSubscriptionPlanDescriptor(plan)
            };

            var now = DateTimeOffset.Now;
            var trialDuration = now > trialEndDate ? trialEndDate - now : TimeSpan.Zero;
            var trialDurationDays = trialDuration > TimeSpan.Zero ? (int)Math.Floor(trialDuration.TotalDays) : 0;

            var request = new SubscriptionRequest
            {
				PaymentMethodToken = paymentMethodToken,
				PlanId = plan.ToString(),
				Descriptor = descriptor,
				TrialDuration = trialDurationDays,
				TrialDurationUnit = SubscriptionDurationUnit.DAY,
				HasTrialPeriod = trialDurationDays > 0
			};

			var result = Gateway.Subscription.Create(request);

			if (result.IsSuccess())
            {
                return result.Target;
            }
			else
            {
                throw new Exception(result.Message);
            }
		}<commit_msg>Fixed Trial end date calculation when creating a Braintree subscrition<commit_after>﻿using Braintree;
using System;
using LcEnum;

public partial class LcPayment
{
    public class Membership
    {
        #region Gateway
        private BraintreeGateway _gateway;

        private BraintreeGateway Gateway
        {
			get {
				if (_gateway == null) {
					_gateway = NewBraintreeGateway();
				}
                return _gateway;
			}
        }
        #endregion

        #region Class
        public Membership() { }
        #endregion

        #region IDs
        /// <summary>
        /// Get the payment gateway ID for a customer based in our userID
        /// with a specific format to use for 'fee payments'; this
        /// allow us to easy distinguish transactions of the user made
        /// to pay membership/ownership fees and payments to other professionals
        /// as a marketplace client (as of LcPayemnt.GetCustomerId)
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public static string GetFeePaymentUserId(int userID)
        {
            return ASP.LcHelpers.Channel + "_fee_" + userID.ToString();
        }
        #endregion

        #region Subscription

        /// <summary>
        /// Returns the correct descriptor name for the given plan,
        /// following gateway naming restrictions.
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        public string GetSubscriptionPlanDescriptor(SubscriptionPlan plan)
        {
            // IMPORTANT: Braintree restricts the naming possibilities
            // as described at https://developers.braintreepayments.com/reference/request/transaction/sale/dotnet#descriptor.name
            // Copied: Company name/DBA section must be either 3, 7 or 12 characters
            // and the product descriptor can be up to 18, 14, or 9 characters respectively (with an * in between
            // for a total descriptor name of 22 characters)
            // NOTE: We choose 12 chars for 'Loconomics  ' (double white space in the end
            // to match twelve) plus short plan name ('ProAnnual' fits exactly, 9)
            switch (plan)
            {
                case SubscriptionPlan.Free:
                    throw new ArgumentException("A free plan don't need a paid subscription");
                case SubscriptionPlan.OwnerProAnnual:
                    return "Loconomics  *ProAnnual";
                case SubscriptionPlan.OwnerPro:
                    return "Loconomics  *Pro";
                case SubscriptionPlan.OwnerGrowth:
                    return "Loconomics  *Growth";
                default:
                    throw new ArgumentException("Plan value unsupported");
            }
        }

        public Subscription CreateSubscription(SubscriptionPlan plan, string paymentMethodToken, DateTimeOffset trialEndDate)
        {
            var descriptor = new DescriptorRequest
            {
                Name = GetSubscriptionPlanDescriptor(plan)
            };

            var now = DateTimeOffset.Now;
            var trialDuration = now > trialEndDate ? TimeSpan.Zero : trialEndDate - now;
            var trialDurationDays = trialDuration > TimeSpan.Zero ? (int)Math.Floor(trialDuration.TotalDays) : 0;

            var request = new SubscriptionRequest
            {
				PaymentMethodToken = paymentMethodToken,
				PlanId = plan.ToString(),
				Descriptor = descriptor,
				TrialDuration = trialDurationDays,
				TrialDurationUnit = SubscriptionDurationUnit.DAY,
				HasTrialPeriod = trialDurationDays > 0
			};

			var result = Gateway.Subscription.Create(request);

			if (result.IsSuccess())
            {
                return result.Target;
            }
			else
            {
                throw new Exception(result.Message);
            }
		}
{'fraction_non_alphanumeric': 0.07817166601740033, 'fraction_numerical': 0.004155304505908323, 'mean_word_length': 1.8589458054936896, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 2, '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': '2475584', 'n_tokens_mistral': 2009, 'n_tokens_neox': 1820, 'n_words': 587}