<commit_before>﻿

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Purchasing.Core.Domain;
using UCDArch.Core.PersistanceSupport;
using UCDArch.Core.Utils;
using UCDArch.Web.ActionResults;
using UCDArch.Web.Attributes;
using System.Web;
using System.Text;
using Purchasing.Core;
using System.Globalization;
using AutoMapper;
using Purchasing.Web.Services;

namespace Purchasing.Web.Controllers
{
    /// <summary>
    /// Controller for the OrderMockup class
    /// </summary>
    public class OrderMockupController : ApplicationController
    {
        private readonly IRepository<Order> _orderRepository;
        private readonly IRepositoryWithTypedId<SubAccount, Guid> _subAccountRepository;
        private readonly IRepositoryFactory _repositoryFactory;
        private readonly IOrderService _orderService;

        public OrderMockupController(IRepository<Order> orderRepository, 
            IRepositoryWithTypedId<SubAccount, Guid> subAccountRepository, 
            IRepositoryFactory repositoryFactory, IOrderService orderService)
        {
            _orderRepository = orderRepository;
            _subAccountRepository = subAccountRepository;
            _repositoryFactory = repositoryFactory;
            _orderService = orderService;
        }

        //
        // GET: /OrderMockup/
        public ActionResult Index()
        {
            return View();
        }


        public new ActionResult Request()
        {
            ViewBag.Units = Repository.OfType<UnitOfMeasure>().GetAll();
            ViewBag.Accounts = Repository.OfType<WorkgroupAccount>().Queryable.Select(x=>x.Account).ToList();
            ViewBag.Vendors = Repository.OfType<WorkgroupVendor>().GetAll();
            ViewBag.Addresses = Repository.OfType<WorkgroupAddress>().GetAll();
            ViewBag.ShippingTypes = Repository.OfType<ShippingType>().GetAll();
            ViewBag.Approvers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.Approver).Select(
                    x => x.User).ToList();
            ViewBag.AccountManagers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.AccountManager).Select(
                    x => x.User).ToList();

            return View();
        }

        [HttpPost]
        [BypassAntiForgeryToken] //TODO: implement the token
        public new ActionResult Request(OrderViewModel model)
        {
            //TODO: no validation will be done!

            var workgroup = _repositoryFactory.WorkgroupRepository.Queryable.First(); //TODO: assocaite with the proper workgroup

            var order = new Order
            {
                Vendor = _repositoryFactory.WorkgroupVendorRepository.GetById(model.Vendor),
                Address = _repositoryFactory.WorkgroupAddressRepository.GetById(model.ShipAddress),
                ShippingType = _repositoryFactory.ShippingTypeRepository.GetById(model.ShippingType),
                DateNeeded = model.DateNeeded,
                AllowBackorder = model.AllowBackorder,
                EstimatedTax = decimal.Parse(model.Tax.TrimEnd('%')),
                Workgroup = workgroup,
                Organization = workgroup.PrimaryOrganization, //why is this needed?
                ShippingAmount = decimal.Parse(model.Shipping.TrimStart('$')),
                DeliverTo = model.ShipTo,
                DeliverToEmail = model.ShipEmail,
                OrderType = Repository.OfType<OrderType>().Queryable.First(), //TODO: why needed?
                CreatedBy = _repositoryFactory.UserRepository.GetById(CurrentUser.Identity.Name),
                Justification = model.Justification
            };

            if (model.FileIds != null)
            {
                foreach (var fileId in model.FileIds)
                {
                    order.AddAttachment(_repositoryFactory.AttachmentRepository.GetById(fileId));
                }
            }

            if (model.Restricted.IsRestricted)
            {
                var restricted = new ControlledSubstanceInformation
                                     {
                                         AuthorizationNum = model.Restricted.Rua,
                                         ClassSchedule = model.Restricted.Class,
                                         Custodian = model.Restricted.Custodian,
                                         EndUser = model.Restricted.Users,
                                         StorageSite = model.Restricted.StorageSite,
                                         Use = model.Restricted.Use
                                     };

                order.SetAuthorizationInfo(restricted);
                order.HasControlledSubstance = true;
            }

            //Add in line items
            foreach (var lineItem in model.Items)
            {
                if (lineItem.IsValid())
                {
                    var commodity = string.IsNullOrWhiteSpace(lineItem.CommodityCode)
                                        ? null
                                        : _repositoryFactory.CommodityRepository.GetById(lineItem.CommodityCode);
                    
                    //TODO: could use automapper later, but need to do validation
                    var orderLineItem = new LineItem
                                            {
                                                CatalogNumber = lineItem.CatalogNumber,
                                                Commodity = commodity,
                                                Description = lineItem.Description,
                                                Notes = lineItem.Notes,
                                                Quantity = decimal.Parse(lineItem.Quantity),
                                                Unit = lineItem.Units,//TODO: shouldn't this link to UOM?
                                                UnitPrice = decimal.Parse(lineItem.Price),
                                                Url = lineItem.Url
                                            };

                    order.AddLineItem(orderLineItem);

                    if (model.SplitType == OrderViewModel.SplitTypes.Line)
                    {
                        var lineItemId = lineItem.Id;

                        //Go through each split created for this line item
                        foreach (var split in model.Splits.Where(x => x.LineItemId == lineItemId))
                        {
                            if (split.IsValid())
                            {
                                order.AddSplit(new Split
                                                   {
                                                       Account = split.Account,
                                                       Amount = decimal.Parse(split.Amount),
                                                       LineItem = orderLineItem,
                                                       SubAccount = split.SubAccount,
                                                       Project = split.Project
                                                   });
                            }
                        }   
                    }
                }
            }

            //TODO: not that I am not checking an order split actually has valid splits, or that they add to the total.
            if (model.SplitType == OrderViewModel.SplitTypes.Order)
            {
                foreach (var split in model.Splits)
                {
                    if (split.IsValid())
                    {
                        order.AddSplit(new Split
                                           {
                                               Account = split.Account,
                                               Amount = decimal.Parse(split.Amount),
                                               SubAccount = split.SubAccount,
                                               Project = split.Project
                                           });
                    }
                }
            }
            else if (model.SplitType == OrderViewModel.SplitTypes.None)
            {
                order.AddSplit(new Split { Amount = order.Total(), Account = model.Account, SubAccount = model.SubAccount, Project = model.Project }); //Order with "no" splits get one split for the full amount
            }

            _orderService.CreateApprovalsForNewOrder(order, accountId: model.Account, approverId: model.Approvers, accountManagerId: model.AccountManagers);

            _orderRepository.EnsurePersistent(order); //TODO: we are just saving the order and not doing any approvals

            return RedirectToAction("ReadOnly", new {id = order.Id});
        }

        /// <summary>
        /// Edit the given order
        /// </summary>
        public ActionResult Edit(int id)
        {
            var model = new OrderEditModel {Order = _orderRepository.GetNullableById(id)};

            Check.Require(model.Order != null);

            if (model.Order.HasControlledSubstance)
            {
                model.ControlledSubstanceInformation =
                    _repositoryFactory.ControlledSubstanceInformationRepository.Queryable.Where(
                        x => x.Order.Id == model.Order.Id).Single();
            }

            /*
            model.Splits = _repositoryFactory.SplitRepository.Queryable.Where(x => x.Order.Id == id).ToList();
            model.LineItems = _repositoryFactory.LineItemRepository.Queryable.Where(x => x.Order.Id == id).ToList();

            if (model.Splits.Any(x => x.LineItem != null))
            {
                model.SplitType = OrderViewModel.SplitTypes.Line;
            }
            else
            {
                model.SplitType = model.Splits.Count() == 1
                                      ? OrderViewModel.SplitTypes.None
                                      : OrderViewModel.SplitTypes.Order;
            }
             */

            model.Units = Repository.OfType<UnitOfMeasure>().GetAll();
            model.Accounts = Repository.OfType<WorkgroupAccount>().Queryable.Select(x => x.Account).ToList();
            model.Vendors = Repository.OfType<WorkgroupVendor>().GetAll();
            model.Addresses = Repository.OfType<WorkgroupAddress>().GetAll();
            model.ShippingTypes = Repository.OfType<ShippingType>().GetAll();
            model.Approvers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.Approver).Select(
                    x => x.User).ToList();
            model.AccountManagers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.AccountManager).Select(
                    x => x.User).ToList();

            return View(model);
        }

        public class OrderEditModel
        {
            public OrderEditModel()
            {
                ControlledSubstanceInformation = new ControlledSubstanceInformation();
                
            }

            public Order Order { get; set; }
            public OrderViewModel.SplitTypes SplitType { get; set; }
            public IList<LineItem> LineItems { get; set; }
            public IList<Split> Splits { get; set; }
            public ControlledSubstanceInformation ControlledSubstanceInformation { get; set; }
            public IList<UnitOfMeasure> Units { get; set; }
            public IList<Account> Accounts { get; set; }<commit_msg>added a placeholder method for the edit action -- I think the proper values are all being passed<commit_after>﻿

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Purchasing.Core.Domain;
using UCDArch.Core.PersistanceSupport;
using UCDArch.Core.Utils;
using UCDArch.Web.ActionResults;
using UCDArch.Web.Attributes;
using System.Web;
using System.Text;
using Purchasing.Core;
using System.Globalization;
using AutoMapper;
using Purchasing.Web.Services;

namespace Purchasing.Web.Controllers
{
    /// <summary>
    /// Controller for the OrderMockup class
    /// </summary>
    public class OrderMockupController : ApplicationController
    {
        private readonly IRepository<Order> _orderRepository;
        private readonly IRepositoryWithTypedId<SubAccount, Guid> _subAccountRepository;
        private readonly IRepositoryFactory _repositoryFactory;
        private readonly IOrderService _orderService;

        public OrderMockupController(IRepository<Order> orderRepository, 
            IRepositoryWithTypedId<SubAccount, Guid> subAccountRepository, 
            IRepositoryFactory repositoryFactory, IOrderService orderService)
        {
            _orderRepository = orderRepository;
            _subAccountRepository = subAccountRepository;
            _repositoryFactory = repositoryFactory;
            _orderService = orderService;
        }

        //
        // GET: /OrderMockup/
        public ActionResult Index()
        {
            return View();
        }


        public new ActionResult Request()
        {
            ViewBag.Units = Repository.OfType<UnitOfMeasure>().GetAll();
            ViewBag.Accounts = Repository.OfType<WorkgroupAccount>().Queryable.Select(x=>x.Account).ToList();
            ViewBag.Vendors = Repository.OfType<WorkgroupVendor>().GetAll();
            ViewBag.Addresses = Repository.OfType<WorkgroupAddress>().GetAll();
            ViewBag.ShippingTypes = Repository.OfType<ShippingType>().GetAll();
            ViewBag.Approvers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.Approver).Select(
                    x => x.User).ToList();
            ViewBag.AccountManagers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.AccountManager).Select(
                    x => x.User).ToList();

            return View();
        }

        [HttpPost]
        [BypassAntiForgeryToken] //TODO: implement the token
        public new ActionResult Request(OrderViewModel model)
        {
            //TODO: no validation will be done!

            var workgroup = _repositoryFactory.WorkgroupRepository.Queryable.First(); //TODO: assocaite with the proper workgroup

            var order = new Order
            {
                Vendor = _repositoryFactory.WorkgroupVendorRepository.GetById(model.Vendor),
                Address = _repositoryFactory.WorkgroupAddressRepository.GetById(model.ShipAddress),
                ShippingType = _repositoryFactory.ShippingTypeRepository.GetById(model.ShippingType),
                DateNeeded = model.DateNeeded,
                AllowBackorder = model.AllowBackorder,
                EstimatedTax = decimal.Parse(model.Tax.TrimEnd('%')),
                Workgroup = workgroup,
                Organization = workgroup.PrimaryOrganization, //why is this needed?
                ShippingAmount = decimal.Parse(model.Shipping.TrimStart('$')),
                DeliverTo = model.ShipTo,
                DeliverToEmail = model.ShipEmail,
                OrderType = Repository.OfType<OrderType>().Queryable.First(), //TODO: why needed?
                CreatedBy = _repositoryFactory.UserRepository.GetById(CurrentUser.Identity.Name),
                Justification = model.Justification
            };

            if (model.FileIds != null)
            {
                foreach (var fileId in model.FileIds)
                {
                    order.AddAttachment(_repositoryFactory.AttachmentRepository.GetById(fileId));
                }
            }

            if (model.Restricted.IsRestricted)
            {
                var restricted = new ControlledSubstanceInformation
                                     {
                                         AuthorizationNum = model.Restricted.Rua,
                                         ClassSchedule = model.Restricted.Class,
                                         Custodian = model.Restricted.Custodian,
                                         EndUser = model.Restricted.Users,
                                         StorageSite = model.Restricted.StorageSite,
                                         Use = model.Restricted.Use
                                     };

                order.SetAuthorizationInfo(restricted);
                order.HasControlledSubstance = true;
            }

            //Add in line items
            foreach (var lineItem in model.Items)
            {
                if (lineItem.IsValid())
                {
                    var commodity = string.IsNullOrWhiteSpace(lineItem.CommodityCode)
                                        ? null
                                        : _repositoryFactory.CommodityRepository.GetById(lineItem.CommodityCode);
                    
                    //TODO: could use automapper later, but need to do validation
                    var orderLineItem = new LineItem
                                            {
                                                CatalogNumber = lineItem.CatalogNumber,
                                                Commodity = commodity,
                                                Description = lineItem.Description,
                                                Notes = lineItem.Notes,
                                                Quantity = decimal.Parse(lineItem.Quantity),
                                                Unit = lineItem.Units,//TODO: shouldn't this link to UOM?
                                                UnitPrice = decimal.Parse(lineItem.Price),
                                                Url = lineItem.Url
                                            };

                    order.AddLineItem(orderLineItem);

                    if (model.SplitType == OrderViewModel.SplitTypes.Line)
                    {
                        var lineItemId = lineItem.Id;

                        //Go through each split created for this line item
                        foreach (var split in model.Splits.Where(x => x.LineItemId == lineItemId))
                        {
                            if (split.IsValid())
                            {
                                order.AddSplit(new Split
                                                   {
                                                       Account = split.Account,
                                                       Amount = decimal.Parse(split.Amount),
                                                       LineItem = orderLineItem,
                                                       SubAccount = split.SubAccount,
                                                       Project = split.Project
                                                   });
                            }
                        }   
                    }
                }
            }

            //TODO: not that I am not checking an order split actually has valid splits, or that they add to the total.
            if (model.SplitType == OrderViewModel.SplitTypes.Order)
            {
                foreach (var split in model.Splits)
                {
                    if (split.IsValid())
                    {
                        order.AddSplit(new Split
                                           {
                                               Account = split.Account,
                                               Amount = decimal.Parse(split.Amount),
                                               SubAccount = split.SubAccount,
                                               Project = split.Project
                                           });
                    }
                }
            }
            else if (model.SplitType == OrderViewModel.SplitTypes.None)
            {
                order.AddSplit(new Split { Amount = order.Total(), Account = model.Account, SubAccount = model.SubAccount, Project = model.Project }); //Order with "no" splits get one split for the full amount
            }

            _orderService.CreateApprovalsForNewOrder(order, accountId: model.Account, approverId: model.Approvers, accountManagerId: model.AccountManagers);

            _orderRepository.EnsurePersistent(order); //TODO: we are just saving the order and not doing any approvals

            return RedirectToAction("ReadOnly", new {id = order.Id});
        }

        /// <summary>
        /// Edit the given order
        /// </summary>
        public ActionResult Edit(int id)
        {
            var model = new OrderEditModel {Order = _orderRepository.GetNullableById(id)};

            Check.Require(model.Order != null);

            if (model.Order.HasControlledSubstance)
            {
                model.ControlledSubstanceInformation =
                    _repositoryFactory.ControlledSubstanceInformationRepository.Queryable.Where(
                        x => x.Order.Id == model.Order.Id).Single();
            }

            /*
            model.Splits = _repositoryFactory.SplitRepository.Queryable.Where(x => x.Order.Id == id).ToList();
            model.LineItems = _repositoryFactory.LineItemRepository.Queryable.Where(x => x.Order.Id == id).ToList();

            if (model.Splits.Any(x => x.LineItem != null))
            {
                model.SplitType = OrderViewModel.SplitTypes.Line;
            }
            else
            {
                model.SplitType = model.Splits.Count() == 1
                                      ? OrderViewModel.SplitTypes.None
                                      : OrderViewModel.SplitTypes.Order;
            }
             */

            model.Units = Repository.OfType<UnitOfMeasure>().GetAll();
            model.Accounts = Repository.OfType<WorkgroupAccount>().Queryable.Select(x => x.Account).ToList();
            model.Vendors = Repository.OfType<WorkgroupVendor>().GetAll();
            model.Addresses = Repository.OfType<WorkgroupAddress>().GetAll();
            model.ShippingTypes = Repository.OfType<ShippingType>().GetAll();
            model.Approvers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.Approver).Select(
                    x => x.User).ToList();
            model.AccountManagers =
                Repository.OfType<WorkgroupPermission>().Queryable.Where(x => x.Role.Id == Role.Codes.AccountManager).Select(
                    x => x.User).ToList();

            return View(model);
        }

        [HttpPost]
        [BypassAntiForgeryToken] //TODO: implement the token
        public ActionResult Edit(int id, OrderViewModel model)
        {
            ErrorMessage = "Warning: No actual saving is being done buy the edit method";
            return RedirectToAction("ReadOnly", new {id});
        }
        public class OrderEditModel
        {
            public OrderEditModel()
            {
                ControlledSubstanceInformation = new ControlledSubstanceInformation();
                
            }

            public Order Order { get; set; }
            public OrderViewModel.SplitTypes SplitType { get; set; }
            public IList<LineItem> LineItems { get; set; }
            public IList<Split> Splits { get; set; }
            public ControlledSubstanceInformation ControlledSubstanceInformation { get; set; }
            public IList<UnitOfMeasure> Units { get; set; }
            public IList<Account> Accounts { get; set; }
{'fraction_non_alphanumeric': 0.08140567513849536, 'fraction_numerical': 8.457732481921597e-05, 'mean_word_length': 1.3560824947693535, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 130, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1367575', 'n_tokens_mistral': 5361, 'n_tokens_neox': 5121, 'n_words': 1054}