Advertisement
Guest User

Untitled

a guest
Mar 30th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 35.94 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using EleWise.ELMA.API;
  5. using EleWise.ELMA.Model.Common;
  6. using EleWise.ELMA.Model.Managers;
  7. using EleWise.ELMA.Model.Entities.ProcessContext;
  8. using Context = EleWise.ELMA.Model.Entities.ProcessContext.P_ObnovlenieProektov;
  9. using Newtonsoft.Json;
  10. using EleWise.ELMA.Security.Managers;
  11. using EleWise.ELMA.CRM.Managers;
  12. using EleWise.ELMA.Model.Services;
  13. using EleWise.ELMA.CRM.Models;
  14. using EleWise.ELMA.ConfigurationModel;
  15. using System.Text.RegularExpressions;
  16. using EleWise.ELMA.Security.Models;
  17. using EleWise.ELMA.Projects;
  18. using SendOpportunity1C;
  19. using EleWise.ELMA.Workflow.Managers;
  20. using EleWise.ELMA.Workflow.Models;
  21.  
  22. namespace EleWise.ELMA.Model.Scripts
  23. {
  24.     /// <summary>
  25.     /// Модуль сценариев процесса "Обновление проектов"
  26.     /// </summary>
  27.     /// <example>
  28.     /// <![CDATA[
  29.     /// >>>>>>>>>>>>>>>ВАЖНАЯ ИНФОРМАЦИЯ!!!<<<<<<<<<<<<<<<
  30.     /// Данный редактор создан для работы с PublicAPI.
  31.     /// PublicAPI предназначен для разработки сценариев ELMA.
  32.     /// Например, с помощью PublicAPI можно добавить комментарий к документу:
  33.     /// //Загружаем документ
  34.     /// var doc = PublicAPI.Docflow.Document.Load(56);
  35.     /// //Добавляем комментарий
  36.     /// PublicAPI.Docflow.Document.AddComment(doc, "тут ваш комментарий");
  37.     ///
  38.     /// Более подробно про PublicAPI вы можете узнать тут: http://www.elma-bpm.ru/kb/article-642ApiRoot.html
  39.     ///
  40.     /// Если же вам нужна более серьёзная разработка, выходящая за рамки PublicAPI, используйте
  41.     /// сторонние редакторы кода, такие как SharpDevelop и VisualStudio.
  42.     /// Информацию по запуску кода в стороннем редакторе вы можете найти тут:
  43.     /// http://www.elma-bpm.ru/kb/article-837.html
  44.     /// ]]>
  45.     /// </example>
  46.     public partial class P_ObnovlenieProektov_Scripts : EleWise.ELMA.Workflow.Scripts.ProcessScriptBase<Context>
  47.     {
  48.         public UserManager UserManager {
  49.             get {
  50.                 return UserManager.Instance;
  51.             }
  52.         }
  53.  
  54.         public IEntityManager<ITEL_PricePolicies, long> PricePoliciesManager {
  55.             get {
  56.                 return EntityManager<ITEL_PricePolicies, long>.Instance;
  57.             }
  58.         }
  59.  
  60.         public ContractorManager ContractorManager {
  61.             get {
  62.                 return ContractorManager.Instance;
  63.             }
  64.         }
  65.  
  66.         public IEntityManager<ITEL_Probability, long> ProbabilityManager {
  67.             get {
  68.                 return EntityManager<ITEL_Probability, long>.Instance;
  69.             }
  70.         }
  71.  
  72.         public SaleManager SaleManager {
  73.             get {
  74.                 return SaleManager.Instance;
  75.             }
  76.         }
  77.  
  78.         public IEntityManager<ITEL_ProductType, long> ProductTypeManager {
  79.             get {
  80.                 return EntityManager<ITEL_ProductType, long>.Instance;
  81.             }
  82.         }
  83.  
  84.         public IEntityManager<ITEL_Project, long> ProjectManager {
  85.             get {
  86.                 return EntityManager<ITEL_Project, long>.Instance;
  87.             }
  88.         }
  89.  
  90.         /// <summary>
  91.         /// Парсим данные из JSON и записываем их в блок
  92.         /// </summary>
  93.         /// <param name="context">Контекст процесса</param>
  94.         public virtual void ParseData (Context context)
  95.         {
  96.             context.Iterator = 0;
  97.             var projects = JsonConvert.DeserializeObject<List<Project>> (context.IncomeJSON);
  98.             foreach (var project in projects) {
  99.                 var contextProject = InterfaceActivator.Create<P_ObnovlenieProektov_Project> ();
  100.                 contextProject.Name = project.Name;
  101.                 contextProject.Manager = project.Manager;
  102.                 contextProject.Contractor = project.Contractor;
  103.                 contextProject.GeneralContractor = project.GeneralContractor;
  104.                 contextProject.ProjectInsitute = project.ProjectInsitute;
  105.                 contextProject.Object = project.Object;
  106.                 contextProject.Description = project.Description;
  107.                 contextProject.ImplementationProbability = project.ImplementationProbability;
  108.                 contextProject.IdELMA = project.IdELMA;
  109.                 contextProject.LinkELMA = project.LinkELMA;
  110.                 contextProject.Link_1C = project.Link_1C;
  111.                 contextProject.Opportunity = project.Opportunity;
  112.                 contextProject.Name_1C = project.Name_1C;
  113.                 foreach (var solution in project.Solution) {
  114.                     var contextSolution = InterfaceActivator.Create<Solutions> ();
  115.                     contextSolution.ProductType = solution.ProductType;
  116.                     contextSolution.Quantity = solution.Quantity;
  117.                     contextSolution.Charge = solution.Charge;
  118.                     contextSolution.SummaryCostPrice = solution.SummaryCostPrice;
  119.                     contextSolution.SupplyDate = solution.SupplyDate;
  120.                     contextProject.Solution.Add (contextSolution);
  121.                 }
  122.                 context.Project.Add (contextProject);
  123.             }
  124.         }
  125.  
  126.         /// <summary>
  127.         /// SendAndCalculateOpportunity
  128.         /// </summary>
  129.         /// <param name="context">Контекст процесса</param>
  130.         public virtual void OpportunityProcessing (Context context)
  131.         {
  132.             var opportunitySender = new SendOpportunity ();
  133.             foreach (var sale in context.Sales) {
  134.                 CalculateOpportunityBudget (sale);
  135.                 var result = opportunitySender.Execute (sale, context.WorkflowInstance);
  136.                 //если удачно, записываем Guid1с возможности
  137.                 if (result.IsSucces) {
  138.                     sale.TEL_Guid1C = result.Message;
  139.                 }
  140.                 sale.Save ();
  141.             }
  142.             context.Sales.Clear ();
  143.         }
  144.  
  145.         /// <summary>
  146.         /// Обрабатывает 10 проектов из блока:
  147.         /// Проекты которые могут быть отправлены - сохраняем и удаляем из блока,
  148.         /// Проекты, которые не могут быть отправлены остаются в блоке
  149.         /// </summary>
  150.         /// <param name="context">Контекст процесса</param>
  151.         public virtual void ProjectProcessing (Context context)
  152.         {
  153.             var operationCount = 0;
  154.             for (int i = (int)context.Iterator; i < context.Iterator + 10 && i < context.Project.Count; i++) {
  155.                 var project = context.Project.ElementAt (i);
  156.                 if (operationCount >= 10) {
  157.                     break;
  158.                 }
  159.                 #region Обязательные условия
  160.                 var manager = FindUser (project.Manager);
  161.                 var contractor = FindContractor (project.Contractor);
  162.                 if (manager == null) {
  163.                     context.Errors.Add (new P_ObnovlenieProektov_Errors {
  164.                         Error = SR.T ("Менеджер проекта с логином '{0}' не найден", project.Manager),
  165.                         ProjectName = project.Name_1C
  166.                     });
  167.                     project.Manager = "";
  168.                 }
  169.                 if (contractor == null) {
  170.                     context.Errors.Add (new P_ObnovlenieProektov_Errors {
  171.                         Error = SR.T ("Контрагент '{0}' не найден", project.Contractor),
  172.                         ProjectName = project.Name_1C
  173.                     });
  174.                     project.Contractor = "";
  175.                 }
  176.                 //заполняем TCC, если оно есть, иначе не создаем проект
  177.                 if (string.IsNullOrEmpty (project.Name_1C)) {
  178.                     context.Errors.Add (new P_ObnovlenieProektov_Errors {
  179.                         Error = SR.T ("Name_1C Пустой"),
  180.                         ProjectName = project.Name_1C
  181.                     });
  182.                 }
  183.                 if (string.IsNullOrEmpty (project.Link_1C)) {
  184.                     context.Errors.Add (new P_ObnovlenieProektov_Errors {
  185.                         Error = SR.T ("Link_1C Пустой"),
  186.                         ProjectName = project.Name_1C
  187.                     });
  188.                 }
  189.                 #endregion
  190.                 //если одно из обязательных полей не заполнено, то переходим к следующему процессу
  191.                 if (contractor == null || manager == null || string.IsNullOrEmpty (project.Link_1C) || string.IsNullOrEmpty (project.Name_1C)) {
  192.                     context.Project.Remove (project);
  193.                     context.Iterator++;
  194.                     operationCount++;
  195.                     continue;
  196.                 }
  197.                 //иначе
  198.                 else {
  199.                     #region возможность и TCC
  200.                     if (!FillContextTCC (contractor, context)) {
  201.                         context.Errors.Add (new P_ObnovlenieProektov_Errors {
  202.                             Error = SR.T ("Контрагент '{0}' не содержит TCC", contractor.Name),
  203.                             ProjectName = project.Name_1C
  204.                         });
  205.                     }
  206.                     var sale = FindOpportunityOrNull (project.Opportunity);
  207.                     if (sale == null && context.TCC != null) {
  208.                         sale = PublicAPI.CRM.Sale.Create ();
  209.                         sale = FillOpportunityOrNull (sale, context, project);
  210.                         //выдаем права на Возможность
  211.                         AddPermisson(sale);
  212.                        
  213.                     }
  214.                     #endregion
  215.                     // если невозможно создать возможность на основе текущих данных переходим к следующему процессу
  216.                     if (context.TCC == null || sale == null) {
  217.                         context.Project.Remove (project);
  218.                         context.Iterator++;
  219.                         operationCount++;
  220.                         continue;
  221.                     }
  222.                     else {
  223.                         var newProject = FindProjectOrNull (project.Name_1C);
  224.                         if (newProject == null) {
  225.                             newProject = CreateProject (project, context);
  226.                             PublicAPI.Projects.Project.PublishProject (newProject);
  227.  
  228.                             FillProject(newProject, project, context);
  229.                             newProject.TEL_Opportunity = sale;
  230.  
  231.                             //Создаем две записи в ЗЦ по вновь созданному проекту.
  232.                             //Ищем контрагента в базе
  233.                             var isPurchaseCenterCreated = false;
  234.                             var ProjectInsitute = FindContractor (project.ProjectInsitute);
  235.                             if (ProjectInsitute == null) {
  236.                                 context.Errors.Add (new P_ObnovlenieProektov_Errors {
  237.                                     Error = SR.T ("Запись в ЗЦ не создаем. Контрагент '{0}' не найден.", project.ProjectInsitute),
  238.                                     ProjectName = project.Name_1C
  239.                                 });
  240.                             }
  241.                             else
  242.                             {
  243.                                 //Создаем запись в ЗЦ для Проектировщика
  244.                                 isPurchaseCenterCreated = TryCreatePurchaseCenter(newProject, ProjectInsitute, "Проектировщик");
  245.                             }
  246.                            
  247.                             //Ищем контрагента в базе
  248.                             var GeneralContractor = FindContractor (project.GeneralContractor);
  249.                             if (GeneralContractor == null) {
  250.                                 context.Errors.Add (new P_ObnovlenieProektov_Errors {
  251.                                     Error = SR.T ("Запись в ЗЦ не создаем. Контрагент '{0}' не найден.", project.GeneralContractor),
  252.                                     ProjectName = project.Name_1C
  253.                                 });
  254.                             }
  255.                             else
  256.                             {
  257.                                 //Создаем запись в ЗЦ для Проектировщика
  258.                                 isPurchaseCenterCreated = TryCreatePurchaseCenter(newProject, GeneralContractor, "Подрядчик");
  259.                             }
  260.                             //если создали закупочный центр добавляем задачу на SSD
  261.                             if (isPurchaseCenterCreated)
  262.                             {
  263.                                 CreateTaskToFillPurchaseCenter(newProject);
  264.                             }
  265.                            
  266.                         }
  267.                         else
  268.                         {
  269.                             FillProject(newProject, project, context);
  270.                             newProject.TEL_Opportunity = sale;
  271.                         }
  272.                        
  273.                         context.Project.Remove (project);
  274.                         //сохраняем возможность и проект
  275.                         sale.Save ();
  276.                         newProject.Save ();
  277.                         //обновление сущности
  278.                         sale.GetId ();
  279.                         newProject.GetId ();
  280.                         //добавляем сейл в список, который будет обрабатываться дальше по процессу
  281.                         context.Sales.Add (sale);
  282.                         context.Projects.Add (newProject);
  283.                         i--;
  284.                         operationCount++;
  285.                     }
  286.                 }
  287.             }
  288.         }
  289.  
  290.         /// <summary>
  291.         /// Добавление прав на Возможность
  292.         /// </summary>
  293.         /// <param name="productName">значение по которому осуществляется фильтрация</param>
  294.         /// <returns></returns>
  295.         private void AddPermisson (Sale sale)
  296.         {
  297.             var usergroup = PublicAPI.Portal.Security.UserGroup.Find ("Name like 'Видимость всех сделок'").FirstOrDefault ();
  298.             if (usergroup != null) {
  299.                 OpportunityFunction.AddPermission.Execute(sale, usergroup, true, false, false, false, false);
  300.             }
  301.             var usergroup2 = PublicAPI.Portal.Security.UserGroup.Find ("Name like 'Просмотр всех возможностей " + sale.TEL_TCC.Code.Trim () + "'").FirstOrDefault ();
  302.             if (usergroup2 != null) {
  303.                 OpportunityFunction.AddPermission.Execute(sale, usergroup2, true, false, false, false, false);
  304.             }
  305.             var usergroup3 = PublicAPI.Portal.Security.UserGroup.Find ("Name like 'Полные права на возможности " + sale.TEL_TCC.Code.Trim () + "'").FirstOrDefault ();
  306.             if (usergroup3 != null) {
  307.                 OpportunityFunction.AddPermission.Execute(sale, usergroup3, false, false, false, false, true);
  308.             }
  309.             if(sale.Responsible != null){
  310.                 OpportunityFunction.AddPermission.Execute(sale, sale.Responsible, true, false, true, false, false);
  311.             }
  312.             if(sale.TEL_SSD != null){
  313.                 OpportunityFunction.AddPermission.Execute(sale, sale.TEL_SSD, true, false, true, false, false);
  314.             }
  315.            
  316.             string posname = "TER_P03_SSD_" + sale.TEL_Segment.Code;
  317.             var position = PublicAPI.Portal.Security.OrganizationItem.Find ("Name like '%" + posname + "%'").FirstOrDefault ();
  318.             if (position != null) {
  319.                 OpportunityFunction.AddPermission.Execute(sale, position, true, false, true, false, false);
  320.             }
  321.             string posname2 = "TER-C-" + sale.TEL_TCC.ShortCode + "_SSD_" + sale.TEL_Segment.Code;
  322.             var position2 = PublicAPI.Portal.Security.OrganizationItem.Find ("Name like '%" + posname2 + "%'").FirstOrDefault ();
  323.             if (position2 != null) {
  324.                 OpportunityFunction.AddPermission.Execute(sale, position2, false, false, false, false, true);
  325.             }
  326.         }
  327.  
  328.         #region Поиск сущностей в базе
  329.         /// <summary>
  330.         /// Поиск PricePolicies по ProductType.Name
  331.         /// </summary>
  332.         /// <param name="productName">значение по которому осуществляется фильтрация</param>
  333.         /// <returns></returns>
  334.         private TEL_PricePolicies FindProductTypeOrNull (string productName)
  335.         {
  336.             var pricePolicies = PricePoliciesManager.Find (p => p.ProductType.Name == productName, FetchOptions.First).FirstOrDefault () as TEL_PricePolicies;
  337.             return pricePolicies;
  338.         }
  339.  
  340.         /// <summary>
  341.         /// Поиск пользователя по имени
  342.         /// </summary>
  343.         /// <param name="name"> значение по которому осуществляется фильтрация</param>
  344.         /// <returns></returns>
  345.         private User FindUser (string name)
  346.         {
  347.             var pattern = @"\w+";
  348.             var match = Regex.Match (name, pattern, RegexOptions.RightToLeft);
  349.             return UserManager.LoadByLogin (match.Value) as User;
  350.         }
  351.  
  352.         /// <summary>
  353.         /// Поиск проекта по Name1c
  354.         /// </summary>
  355.         /// <param name="name1c"> значение по которому осуществляется фильтрация</param>
  356.         /// <returns></returns>
  357.         private TEL_Project FindProjectOrNull (string name1c)
  358.         {
  359.             var filter = new Filter ();
  360.             filter.Query = String.Format ("Name1c = '{0}'", name1c);
  361.             var projectCollection = ProjectManager.Find (filter, FetchOptions.First);
  362.             if (projectCollection.Count == 0) {
  363.                 return null;
  364.             }
  365.             else {
  366.                 return projectCollection.FirstOrDefault () as TEL_Project;
  367.             }
  368.         }
  369.  
  370.         /// <summary>
  371.         /// Поиск контрагента по id1c
  372.         /// </summary>
  373.         /// <param name="id1c">значение по которому осуществляется фильтрация</param>
  374.         /// <returns></returns>
  375.         private Contractor FindContractor (string id1c)
  376.         {
  377.             var filter = InterfaceActivator.Create<IContractorFilter> ();
  378.             filter.Query = String.Format ("TEL_Id1C = '{0}'", id1c);
  379.             return ContractorManager.Find (filter, FetchOptions.First).FirstOrDefault () as Contractor;
  380.         }
  381.  
  382.         /// <summary>
  383.         /// Поиск Probability по числу double, которое равно % вероятности реализации проекта
  384.         /// </summary>
  385.         /// <param name="doubleProbability">значение по которому осуществляется фильтрация</param>
  386.         /// <returns></returns>
  387.         private TEL_Probability FindProbability (string doubleProbability)
  388.         {
  389.             var probability = double.Parse (doubleProbability.Replace (".", ","));
  390.             return ProbabilityManager.Find (p => p.Double == probability, FetchOptions.First).FirstOrDefault () as TEL_Probability;
  391.         }
  392.  
  393.         /// <summary>
  394.         /// Поиск возвомжности по TEL_Guid1c
  395.         /// </summary>
  396.         /// <param name="opportunity">значение по которому осуществляется фильтрация</param>
  397.         /// <returns></returns>
  398.         private Sale FindOpportunityOrNull (string opportunity)
  399.         {
  400.             if (opportunity == "00000000-0000-0000-0000-000000000000") {
  401.                 return null;
  402.             }
  403.             var opportunityFilter = InterfaceActivator.Create<ISaleFilter> ();
  404.             opportunityFilter.Query = System.String.Format (" TEL_Guid1C='{0}' ", opportunity);
  405.             return SaleManager.Find (opportunityFilter, FetchOptions.First).FirstOrDefault () as Sale;
  406.         }
  407.  
  408.         #endregion
  409.         #region расчет\заполнение
  410.         /// <summary>
  411.         /// Расчет бюджета возможности
  412.         /// </summary>
  413.         /// <param name="sale"></param>
  414.         private void CalculateOpportunityBudget (Sale sale)
  415.         {
  416.             double? budget = 0;
  417.             var filter = new Filter ();
  418.             filter.Query = string.Format ("TEL_Opportunity = {0} AND ProjectLifeCycleStage in (Name <> 'Отменен')", sale.Id);
  419.             var projects = ProjectManager.Find (filter, FetchOptions.All);
  420.             budget = projects.Sum (p => p.TEL_ProfitTotal);
  421.             sale.TEL_Budget = budget.ToString ();
  422.         }
  423.  
  424.         /// <summary>
  425.         /// Заполняем TCC по Контрагенту
  426.         /// </summary>
  427.         /// <param name="contractor"></param>
  428.         /// <param name="context"></param>
  429.         private bool FillContextTCC (Contractor contractor, Context context)
  430.         {
  431.             context.TCC = null;
  432.             if (contractor == null) {
  433.                 return false;
  434.             }
  435.             if (contractor.Region == null) {
  436.                 return false;
  437.             }
  438.             if (contractor.Region.TEL_TCC == null) {
  439.                 return false;
  440.             }
  441.             context.TCC = contractor.Region.TEL_TCC;
  442.             return true;
  443.         }
  444.  
  445.         /// <summary>
  446.         /// заполнение возможности
  447.         /// </summary>
  448.         /// <param name="sale">созданная возможность</param>
  449.         /// <param name="context">контекст</param>
  450.         /// <param name="project">проект из контекста</param>
  451.         /// <returns></returns>
  452.         private Sale FillOpportunityOrNull (Sale sale, Context context, P_ObnovlenieProektov_Project project)
  453.         {
  454.             var contractor = FindContractor (project.Contractor);
  455.             var author = FindUser ("admin");
  456.             var responsible = FindUser (project.Manager);
  457.             if (contractor.TEL_Segment == null) {
  458.                 context.Errors.Add (new P_ObnovlenieProektov_Errors {
  459.                     Error = SR.T ("У контрагента '{0}' не заполнено поле 'сегмент'", contractor.Name),
  460.                     ProjectName = project.Name_1C
  461.                 });
  462.                 return null;
  463.             }
  464.             if (contractor.TEL_Segment == null) {
  465.                 return null;
  466.             }
  467.             var SSD = GetSSDbySegment.GetSSDbySegment.GetSSD (context.TCC, contractor.TEL_Segment);
  468.             if (SSD == null) {
  469.                 context.Errors.Add (new P_ObnovlenieProektov_Errors {
  470.                     Error = SR.T ("Нет пользователя на должности SSD"),
  471.                     ProjectName = project.Name_1C
  472.                 });
  473.                 return null;
  474.             }
  475.             sale.TEL_SSD = SSD;
  476.             sale.Name = OpportunityNumberGeneration (context);
  477.             sale.Contractor = contractor;
  478.             sale.Author = author;
  479.             sale.Responsible = responsible;
  480.             sale.TEL_TCC = context.TCC;
  481.             sale.TEL_Segment = contractor.TEL_Segment;
  482.             sale.SaleStatus = PublicAPI.Enums.CRM.Enums.SaleStatus.Active;
  483.             sale.Description = project.Description;
  484.             sale.TEL_Theme = project.Object;
  485.             sale.InheritPermissions = false;
  486.             sale.SaleFunnel = PublicAPI.CRM.Objects.SaleFunnel.Load (1L);
  487.             sale.TEL_Region = contractor.Region;
  488.             sale.TEL_InfoSource = "первичная синхронизация из 1С";
  489.             sale.SaleStage = FindSaleStage ("Активна");
  490.             return sale;
  491.         }
  492.  
  493.         /// <summary>
  494.         /// Поиск стадии сделки
  495.         /// </summary>
  496.         /// <param name="stageName"></param>
  497.         /// <returns></returns>
  498.         private SaleStage FindSaleStage (string stageName)
  499.         {
  500.             return EntityManager<ISaleStage, long>.Instance.Find (s => s.Name == stageName, FetchOptions.First).FirstOrDefault () as SaleStage;
  501.         }
  502.  
  503.         /// <summary>
  504.         /// Заполнение проекта из контекста
  505.         /// </summary>
  506.         /// <param name="newProject"></param>
  507.         /// <param name="project"></param>
  508.         private void FillProject (TEL_Project newProject, P_ObnovlenieProektov_Project project, Context context)
  509.         {
  510.             var projectManager = FindUser (project.Manager);
  511.             var contractor = FindContractor (project.Contractor);
  512.         //  var generalContractor = FindContractor (project.GeneralContractor);
  513.             var probability = FindProbability (project.ImplementationProbability);
  514.             var solutions = CreateSolutions (project, context);
  515.             newProject.TEL_Contractor = contractor;
  516.         //  newProject.Contractor = generalContractor;
  517.             newProject.TEL_Probability = probability;
  518.             newProject.Name1c = project.Name_1C;
  519.             newProject.TEL_Object = project.Object;
  520.             newProject.TEL_ContractorsTrouble = project.Description;
  521.             newProject.Guid1C = project.Link_1C;
  522.             newProject.TEL_MarginTotal = project.TEL_MarginTotal;
  523.             newProject.TEL_ProfitTotal = project.TEL_ProfitTotal;
  524.             newProject.TEL_Segment = contractor.TEL_Segment;
  525.             newProject.TEL_Supply = true;
  526.             newProject.TEL_Solutions.Clear ();
  527.             newProject.TEL_Solutions.AddAll (solutions);
  528.             CalculateTotalProfit (newProject);
  529.             TeamAssign (newProject, projectManager);
  530.             newProject.TEL_Budget = newProject.TEL_ProfitTotal.ToString ();
  531.             //Проверяем на НУЛЛ, т.к. заполняем только при первичном создании. При обновлениях не трогаем, т.к. может быть изменен уже менеджером/ССД при работе.
  532.             if(newProject.TEL_ProjectType == null){
  533.                 var type = EntityManager<TEL_ProjectType>.Instance.Find(c => c.Name == "Single").FirstOrDefault();
  534.                 if(type != null){
  535.                     newProject.TEL_ProjectType = type;
  536.                 }
  537.             }
  538.         }
  539.  
  540.         /// <summary>
  541.         /// Добавляем команду на проект
  542.         /// </summary>
  543.         /// <param name="project"></param>
  544.         /// <param name="user"></param>
  545.         private void TeamAssign (TEL_Project project, User user)
  546.         {
  547.             //добавляем менеджера проекта
  548.             if (user != null) {
  549.                 var projectRole = PublicAPI.Projects.ProjectRole.Filter ().Query ("Name like ’%AM%’ and Project = " + project.Id.ToString ()).Find ().FirstOrDefault ();
  550.                 //Получаем всех текущих пользователей в Роли и обнуляем. На тот случай, если произошли изменения в 1С.
  551.                 //Bez Try padaet metod, esli net polzovateley
  552.                 try{
  553.                     var alluser = PublicAPI.Projects.ProjectRole.GetAllProjectRoleUsers(project, projectRole);
  554.                     PublicAPI.Projects.ProjectRole.RemoveUserFromProjectRole (project, projectRole, alluser);
  555.                 }
  556.                 catch
  557.                 {
  558.                    
  559.                 }
  560.                 //Добавялем найденного ССД
  561.                 PublicAPI.Projects.ProjectRole.AddUserToProjectRole (project, projectRole, user);
  562.             }
  563.             //добавляем SSD
  564.             var SSD = GetSSDbySegment.GetSSDbySegment.GetSSD (project.TEL_Contractor.Region.TEL_TCC, project.TEL_Contractor.TEL_Segment);
  565.             if (SSD != null) {
  566.                 var projectRole = PublicAPI.Projects.ProjectRole.Filter ().Query ("Name like ’%SSD%’ and Project = " + project.Id.ToString ()).Find ().FirstOrDefault ();
  567.                 //Получаем всех текущих пользователей в Роли и обнуляем. На тот случай, если произошли изменения в 1С.
  568.                 try{
  569.                     var alluser = PublicAPI.Projects.ProjectRole.GetAllProjectRoleUsers(project, projectRole);
  570.                     PublicAPI.Projects.ProjectRole.RemoveUserFromProjectRole (project, projectRole, alluser);
  571.                 }
  572.                 catch
  573.                 {
  574.                    
  575.                 }
  576.                 //Добавялем найденного ССД
  577.                 PublicAPI.Projects.ProjectRole.AddUserToProjectRole (project, projectRole, SSD);
  578.             }
  579.            
  580.             //Добавляем ПЕМ
  581.             var PEM = GetSSDbySegment.GetPEMbySegment.GetPEM(project.TEL_Contractor.Region.TEL_TCC);
  582.             if (PEM != null) {
  583.                 var projectRole = PublicAPI.Projects.ProjectRole.Filter ().Query ("Name like ’%Наблюдатели проекта%’ and Project = " + project.Id.ToString ()).Find ().FirstOrDefault ();
  584.                 //Получаем всех текущих пользователей в Роли и обнуляем. На тот случай, если произошли изменения в 1С.
  585.                 try{
  586.                     var alluser = PublicAPI.Projects.ProjectRole.GetAllProjectRoleUsers(project, projectRole);
  587.                     PublicAPI.Projects.ProjectRole.RemoveUserFromProjectRole (project, projectRole, alluser);
  588.                 }
  589.                 catch
  590.                 {
  591.                    
  592.                 }
  593.                 //Добавялем найденного ПЕМ
  594.                 PublicAPI.Projects.ProjectRole.AddUserToProjectRole (project, projectRole, PEM);
  595.             }
  596.         }
  597.  
  598.         /// <summary>
  599.         /// подсчет выручки с проекта (профита, рентабильности и маржи)
  600.         /// </summary>
  601.         /// <param name="project"></param>
  602.         private void CalculateTotalProfit (TEL_Project project)
  603.         {
  604.             project.TEL_MarginTotal = 0;
  605.             project.TEL_ProfitTotal = 0;
  606.             foreach (var solution in project.TEL_Solutions) {
  607.                 project.TEL_MarginTotal += solution.Margin;
  608.                 project.TEL_ProfitTotal += solution.Profit;
  609.             }
  610.             project.TEL_ProfitabilityTotal = Math.Round (Convert.ToDouble ((project.TEL_MarginTotal / project.TEL_ProfitTotal) * 100), 2);
  611.         }
  612.  
  613.         /// <summary>
  614.         /// Пересчет солюшена
  615.         /// </summary>
  616.         /// <param name="solution">возможность</param>
  617.         /// <returns></returns>
  618.         private TEL_Project_TEL_Solutions CalculateSolutionOrReturnNull (Solutions solution, Context context, P_ObnovlenieProektov_Project project)
  619.         {
  620.             var resultSolution = new TEL_Project_TEL_Solutions ();
  621.             resultSolution.TEL_ProductType = FindProductTypeOrNull (solution.ProductType);
  622.             if (resultSolution.TEL_ProductType == null) {
  623.                 context.Errors.Add (new P_ObnovlenieProektov_Errors {
  624.                     ProjectName = project.Name_1C,
  625.                     Error = string.Format ("ProductType c  названием '{0}' не найден", solution.ProductType)
  626.                 });
  627.                 return null;
  628.             }
  629.             resultSolution.Charge = double.Parse (solution.Charge.Replace (".", ","));
  630.             resultSolution.UnitCost = double.Parse (solution.SummaryCostPrice.Replace (".", ","));
  631.             resultSolution.TEL_SupplyDate = DateTime.Parse (solution.SupplyDate);
  632.             resultSolution.Quantity = int.Parse (solution.Quantity);
  633.             resultSolution.SummaryCostPrice = resultSolution.UnitCost * resultSolution.Quantity;
  634.             resultSolution.Margin = resultSolution.Charge * resultSolution.Quantity * resultSolution.UnitCost / 100;
  635.             resultSolution.Profit = resultSolution.Margin + resultSolution.UnitCost * resultSolution.Quantity;
  636.             resultSolution.Profitability = Math.Round (Convert.ToDouble ((resultSolution.Margin / resultSolution.Profit) * 100), 2).ToString () + "%";
  637.             resultSolution.TEL_ProductGroup = resultSolution.TEL_ProductType.Solution;
  638.             return resultSolution;
  639.         }
  640.  
  641.         /// <summary>
  642.         /// Пересчет количества проектов, в которых есть все обязательные поля
  643.         /// </summary>
  644.         /// <param name="context"> контекст</param>
  645.         /// <returns> количество проектов, в которых все обязательные поля заполнены</returns>
  646.         public virtual int ProjectToSendCount (Context context)
  647.         {
  648.             int count = 0;
  649.             foreach (var project in context.Project) {
  650.                 if (project.Manager != "" && project.Contractor != "" && project.Link_1C != "" && project.Name_1C != "") {
  651.                     count++;
  652.                 }
  653.             }
  654.             return count;
  655.         }
  656.  
  657.         #endregion
  658.         #region создание
  659.         /// <summary>
  660.         /// Создание Даты окончания процесса (учитывает возможности внутри проекта)
  661.         /// </summary>
  662.         /// <param name="project"></param>
  663.         /// <returns></returns>
  664.         private DateTime CreateEndDate (P_ObnovlenieProektov_Project project)
  665.         {
  666.             var endDate = DateTime.Today.AddDays (7);
  667.             foreach (var solution in project.Solution) {
  668.                 DateTime newDate;
  669.                 if (DateTime.TryParse (solution.SupplyDate, out newDate)) {
  670.                     endDate = newDate;
  671.                 }
  672.             }
  673.             return endDate;
  674.         }
  675.  
  676.         /// <summary>
  677.         /// Создание солюшена
  678.         /// </summary>
  679.         /// <param name="project">проект, который хранится в контексте процесса</param>
  680.         /// <returns></returns>
  681.         private ISet<TEL_Project_TEL_Solutions> CreateSolutions (P_ObnovlenieProektov_Project project, Context context)
  682.         {
  683.             var solutions = new HashSet<TEL_Project_TEL_Solutions> ();
  684.             foreach (var solution in project.Solution) {
  685.                 var calculatedSolution = CalculateSolutionOrReturnNull (solution, context, project);
  686.                 if (calculatedSolution != null) {
  687.                     solutions.Add (calculatedSolution);
  688.                 }
  689.             }
  690.             return solutions;
  691.         }
  692.  
  693.         /// <summary>
  694.         /// Создание проекта на основе контекста
  695.         /// </summary>
  696.         /// <param name="project"></param>
  697.         /// <param name="context"></param>
  698.         /// <returns></returns>
  699.         private TEL_Project CreateProject (P_ObnovlenieProektov_Project project, Context context)
  700.         {
  701.             var startDate = DateTime.Now.Date;
  702.             var projectName = ProjectNumberGeneration (context);
  703.             var projectManager = FindUser (project.Manager);
  704.             var endDate = CreateEndDate (project);
  705.             var newProject = PublicAPI.Projects.Types.UserTEL_Project.Create (projectName, projectManager, startDate, endDate);
  706.             return newProject;
  707.         }
  708.  
  709.         /// <summary>
  710.         /// Создание запись ЗЦ на основе контекста
  711.         /// </summary>
  712.         /// <param name="project"></param>
  713.         /// <param name="context"></param>
  714.         /// <returns></returns>
  715.         private bool TryCreatePurchaseCenter (TEL_Project project, Contractor cont, string str)
  716.         {
  717.             var role = EntityManager<TEL_CompanyRole>.Instance.Find(c => c.Name == str).FirstOrDefault();
  718.             if(project != null && project.TEL_Opportunity != null && role != null && project.TEL_Contractor != null){
  719.                 var newPurch = EntityManager<TEL_PurchaseCenter>.Instance.Create();
  720.                     newPurch.CompanyRole = role;
  721.                     newPurch.Company = cont;
  722.                     newPurch.TEL_Opportunity = project.TEL_Opportunity;
  723.                     newPurch.TEL_Projects.Add(project);
  724.                     newPurch.Save();
  725.                 return true;
  726.             }
  727.             return false;
  728.         }
  729.        
  730.         private void CreateTaskToFillPurchaseCenter(TEL_Project project)
  731.         {
  732.             //var startableProcess = PublicAPI.Processes.ProcessHeader.Find("Token = 'eac48672-837c-4db1-865e-a3f269b65a2f'").FirstOrDefault(a => a.Published != null);
  733.             var startableProcess = ProcessHeaderManager.Instance.Find(p => p.Token == "eac48672-837c-4db1-865e-a3f269b65a2f" && p.Published != null, FetchOptions.First).FirstOrDefault() as ProcessHeader;
  734.             if (startableProcess != null)
  735.             {
  736.                 Action<dynamic> processContext = context => {
  737.                     context.Project = project;
  738.                     context.SSD = project.TEL_Opportunity.TEL_SSD ?? project.Manager;
  739.                 };
  740.                 var instance = PublicAPI.Processes.WorkflowInstance.StartProcess(startableProcess.Published, "Заполнение закупочного центра по проекту " + project.Name, processContext);
  741.             }
  742.         }
  743.        
  744.         #endregion
  745.         public class Project
  746.         {
  747.             public string Name {
  748.                 get;
  749.                 set;
  750.             }
  751.  
  752.             public string Manager {
  753.                 get;
  754.                 set;
  755.             }
  756.  
  757.             public string Contractor {
  758.                 get;
  759.                 set;
  760.             }
  761.  
  762.             public string ProjectInsitute {
  763.                 get;
  764.                 set;
  765.             }
  766.  
  767.             public string GeneralContractor {
  768.                 get;
  769.                 set;
  770.             }
  771.  
  772.             public string Object {
  773.                 get;
  774.                 set;
  775.             }
  776.  
  777.             public string Description {
  778.                 get;
  779.                 set;
  780.             }
  781.  
  782.             public string ImplementationProbability {
  783.                 get;
  784.                 set;
  785.             }
  786.  
  787.             public string IdELMA {
  788.                 get;
  789.                 set;
  790.             }
  791.  
  792.             public string LinkELMA {
  793.                 get;
  794.                 set;
  795.             }
  796.  
  797.             public string Link_1C {
  798.                 get;
  799.                 set;
  800.             }
  801.  
  802.             public string Opportunity {
  803.                 get;
  804.                 set;
  805.             }
  806.  
  807.             public string Name_1C {
  808.                 get;
  809.                 set;
  810.             }
  811.  
  812.             public List<Solution> Solution {
  813.                 get;
  814.                 set;
  815.             }
  816.         }
  817.  
  818.         public class Solution
  819.         {
  820.             public string ProductType {
  821.                 get;
  822.                 set;
  823.             }
  824.  
  825.             public string Quantity {
  826.                 get;
  827.                 set;
  828.             }
  829.  
  830.             public string Charge {
  831.                 get;
  832.                 set;
  833.             }
  834.  
  835.             public string SummaryCostPrice {
  836.                 get;
  837.                 set;
  838.             }
  839.  
  840.             public string SupplyDate {
  841.                 get;
  842.                 set;
  843.             }
  844.         }
  845.  
  846.         /// <summary>
  847.         /// Проверка: остались ли проекты, которые можно сохранить в базу
  848.         /// </summary>
  849.         /// <param name="context">Контекст процесса</param>
  850.         /// <param name="GatewayVar"></param>
  851.         public virtual bool ProjectToSend (Context context, object GatewayVar)
  852.         {
  853.             return ProjectToSendCount (context) != 0;
  854.         }
  855.  
  856.         /// <summary>
  857.         /// Генерация имени проекта
  858.         /// </summary>
  859.         /// <param name="context"></param>
  860.         /// <returns></returns>
  861.         public string ProjectNumberGeneration (Context context)
  862.         {
  863.             //скопировано из процесса создания проекта
  864.             var numerator = PublicAPI.Docflow.Objects.Nomenclature.Numerator.Load (new Guid ("4463400e-d257-4cbe-8013-fcad4cc7421e"));
  865.             numerator.Value++;
  866.             numerator.Save ();
  867.             var a = 4 - numerator.Value.ToString ().Length;
  868.             string b = "";
  869.             while (a > 0) {
  870.                 b += "0";
  871.                 a--;
  872.             }
  873.             b += numerator.Value.ToString ();
  874.             return context.TCC.ShortCode + "_P_" + DateTime.Today.Year.ToString ().Substring (2, 2) + b;
  875.         }
  876.  
  877.         /// <summary>
  878.         /// Генерация имени возможности
  879.         /// </summary>
  880.         /// <param name="context"></param>
  881.         /// <returns></returns>
  882.         public string OpportunityNumberGeneration (Context context)
  883.         {
  884.             //скопировано из процесса создания возможности
  885.             var numerator = PublicAPI.Docflow.Objects.Nomenclature.Numerator.Load (new Guid ("b1534790-59e8-44de-a881-3143de902303"));
  886.             numerator.Value++;
  887.             numerator.Save ();
  888.             var a = 4 - numerator.Value.ToString ().Length;
  889.             string b = "";
  890.             while (a > 0) {
  891.                 b += "0";
  892.                 a--;
  893.             }
  894.             b += numerator.Value.ToString ();
  895.             return context.TCC.ShortCode + "_O_" + DateTime.Today.Year.ToString ().Substring (2, 2) + b;
  896.         }
  897.  
  898.        
  899.  
  900.         /// <summary>
  901.         /// Zapusk100ProcessovSozdaniyaProekta
  902.         /// </summary>
  903.         /// <param name="context">Контекст процесса</param>
  904.         public virtual void Zapusk100ProcessovSozdaniyaProekta (Context context)
  905.         {
  906.             if(context.ProjectsToPEM.Count > 0)
  907.             {
  908.                 int n = context.ProjectsToPEM.Count;
  909.                 int i = n;
  910.                 while (i <= n + (n < 100 ? n : 99) && n >= 0)
  911.                 {
  912.                     var prj = context.ProjectsToPEM.FirstOrDefault();
  913.                     if(prj != null)
  914.                     {
  915.                         var startableProcess = PublicAPI.Processes.ProcessHeader.Find ("Name like 'Создание проекта'").FirstOrDefault (a => a.Published != null);
  916.                         if (startableProcess != null) {
  917.                             Action<dynamic> processContext = myContext =>  {
  918.                                 myContext.TEL_Project = prj;
  919.                                 myContext.TCC = EntityManager<TEL_TCC, long>.Instance.Find("ShortCode   = '" + prj.Name.Substring(0,3) + "'").FirstOrDefault();
  920.                                 myContext.MassImport = true;
  921.                             };
  922.                             var instance = PublicAPI.Processes.WorkflowInstance.StartProcess (startableProcess.Published, "Создание проекта " + prj.Name, processContext);
  923.                             context.ProcesList.Add(instance);
  924.                         }
  925.                     }
  926.                     n--;
  927.                     context.ProjectsToPEM.Remove(prj);
  928.                 }
  929.                
  930.             }
  931.             context.PtoPEMpty = context.ProjectsToPEM.Count () > 0;
  932.             context.HasErrors =  context.Errors.Count () > 0;
  933.         }
  934.  
  935.         /// <summary>
  936.         /// ProjectCopy
  937.         /// </summary>
  938.         /// <param name="context">Контекст процесса</param>
  939.         public virtual void ProjectCopy (Context context)
  940.         {
  941.             foreach(var item in context.Projects)
  942.             {
  943.                 context.ProjectsToPEM.Add(item);
  944.             }
  945.         }
  946.     }
  947. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement