public Task <Result <Guid> > Add(CreateInvoiceModel model)
 => _invoiceBiz.Add(model);
        private async Task <Result <(Guid, bool)> > PerformActions(UserSurvey userSurvey)
        {
            var actionGroups = userSurvey.UserAnswer.SelectMany(ua => ua.Answer.Action).GroupBy(a => a.Type);

            bool makeAppointment = false;
            var  invoiceId       = Guid.Empty;

            for (int i = 0; i < actionGroups.OrderBy(a => a.Key).Reverse().Count(); i++)
            {
                var action = actionGroups.ToList()[i];
                var type   = (ActionType)action.Key;
                switch (type)
                {
                case ActionType.CreateAppointment:
                    makeAppointment = true;
                    break;

                case ActionType.AddDependent:
                    break;

                case ActionType.SendTicketAndCreateAppointment:
                    await _ticketBiz.Add(new CreateTicketModel
                    {
                        Priority = TicketPriority.Medium,
                        Text     =
                            "Survey Was Too Complex For Online Process , Please Review Booked Consultation For This User.",
                        Title = "Survey", UserId = generalDataService.User.Id
                    }, userSurvey, false);

                    makeAppointment = true;
                    break;
                }
            }

            var amount = 95 +
                         (userSurvey.UserDependentSurvey.Count * 95);
            decimal tax = (decimal)amount * 5 / 100;

            var hasSpouse  = actionGroups.Any(a => a.Key == (int)ActionType.AddSpouse);
            var spouseText = "";

            if (hasSpouse)
            {
                spouseText = "Spousal Income Tax : 1 x $95 \n";
            }
            var dependentCount = userSurvey.UserDependentSurvey.Count;

            if (hasSpouse)
            {
                dependentCount--;
            }
            var dependentText = "";

            if (dependentCount > 0)
            {
                dependentText = $"+19 Dependent Income Tax : {dependentCount} x $95 \n";
            }
            var mainuserText = "";

            if (dependentCount > 0)
            {
                mainuserText = $"Main User Income Tax Return : 1 x $95 \n";
            }
            invoiceId = (await _invoiceBiz.Add(new CreateInvoiceModel
            {
                Amount = amount,
                Description =
                    $"{mainuserText} {spouseText} {dependentText} SubTotal = ${amount} \n Taxes(GST)= ${(decimal)tax} \n Total = ${(decimal)(amount + tax)}",

                Title = "Personal Tax Return",
                UserSurveyId = userSurvey.Id,
                Enabled = true,
                Status = InvoiceStatus.Pending, UserId = generalDataService.User.Id
            },
                                               userSurvey)).Data;


            await _taxBiz.AddForSurvey(new CreateTaxModel
            {
                UserId      = generalDataService.User.Id, Title = userSurvey.Survey.Name,
                Description = userSurvey.Survey.Description, Enabled = true,
                Status      = makeAppointment ? TaxStatus.SetConsultation : TaxStatus.PaymentPending
            }, userSurvey);

            return(Result <(Guid, bool)> .Successful((invoiceId, makeAppointment)));
        }
        public Task <Result <object> > Add(CreateAppointmentModel model)
        => Result <object> .TryAsync(async() =>
        {
            var isAdmin = generalDataService.User.Permissions.Any(p => p == (int)PermissionType.Admin);

            if (model.UserId == Guid.Empty)
            {
                model.UserId = generalDataService.User.Id;
            }
            var user = (await _membershipServiceApi.SystemUserApiService.Get(
                            new MembershipService.ApiClient.Models.BaseModel {
                Id = model.UserId
            })).Data;
            if (user == null)
            {
                return(Result <object> .Failed(Error.WithData(1000, new[] { "User not found" })));
            }

            var validateAppointment = await _appointmentExceptionBiz.ValidateAppointment(model.Date);
            if (validateAppointment.Success && validateAppointment.Data)
            {
                return(Result <object> .Failed(Error.WithData(1000,
                                                              new[] { "Sorry , there are no available representative in the requested time" })));
            }

            var duplicateTime =
                await _repository.FirstOrDefaultAsNoTrackingAsync <Appointment>(a => a.Date == model.Date);
            if (duplicateTime.Success && duplicateTime.Data != null)
            {
                return(Result <object> .Failed(Error.WithData(1000,
                                                              new[] { "Sorry , there are no available representative in the requested time" })));
            }

            Guid?invoiceId = null;
            if (model.Duration > 20)
            {
                invoiceId = (await _invoiceBiz.Add(new CreateInvoiceModel
                {
                    Amount = 200,
                    Description = @"1xVIP appointment $200 
Sub total = $200
Taxes = $10
Total = $210",
                    Status = InvoiceStatus.Pending,
                    Title = "VIP Appointment",
                    Enabled = true,
                    UserId = model.UserId
                })).Data;
            }

            var appointment = new Appointment
            {
                Id               = Guid.NewGuid(),
                InvoiceId        = invoiceId,
                Description      = model.Description,
                CreationDate     = DateTime.Now,
                Date             = model.Date,
                Duration         = model.Duration,
                Type             = model.Type,
                UserId           = !isAdmin ? generalDataService.User.Id : user.Id,
                RepresentativeId = isAdmin ? generalDataService.User.Id : Guid.Empty,
                Title            = model.Title,
                Approved         = true
            };

            _repository.Add(appointment);

            var usersurvey = await _repository.ListAsync <UserSurvey>(us => us.UserId == generalDataService.User.Id);
            if (usersurvey.Success && usersurvey.Data != null && usersurvey.Data.Any())
            {
                var userSurveyIds = usersurvey.Data.Select(us => us.Id).ToList();
                var taxes         = await _repository.ListAsync <Tax>(t =>
                                                                      t.UserSurveyId != null && userSurveyIds.Contains(t.UserSurveyId.Value) &&
                                                                      t.Status == (int)TaxStatus.SetConsultation);

                if (taxes.Success && taxes.Data != null && taxes.Data.Any())
                {
                    taxes.Data.ToList().ForEach(t => t.Status = (byte)TaxStatus.PendingConsultation);
                }
            }

            await _repository.CommitAsync();


            if (appointment.InvoiceId == null)
            {
                _coreSmtpClient.SendComplimentryConsultation(user.Email,
                                                             user.Firstname + " " + user.Lastname, appointment.Date.ToString("F"));


                await _messageBiz.Add(new CreateMessageModel
                {
                    Title = "Your Appointment",
                    Body  =
                        $"Your appointment has been confirmed. One of our AccNet representatives will reach out to you at the scheduled time : {appointment.Date.ToString("F")} (PACIFIC STANDARD TIME)",
                    ToUser   = user.Id,
                    Priority = MessagePriority.High
                });

                _coreSmtpClient.SendAppointmentBookNotif("*****@*****.**",
                                                         user.Firstname + " " + user.Lastname,
                                                         appointment.Date.ToString("F"));
            }

            return(Result <object> .Successful(new
            {
                message = invoiceId.HasValue
                        ? $"To confirm your VIP consultation on {appointment.Date.ToString("F")} (PACIFIC STANDARD TIME), please click OK to kindly pay the fee for this call. Once paid you will receive a confirmation email detailing the selected date and time. Thank you"
                        : $"Your appointment has been confirmed. One of our AccNet representatives will reach out to you at the scheduled time : {appointment.Date.ToString("F")} (PACIFIC STANDARD TIME)",
                vip = invoiceId.HasValue
            }));
        });